വിക്കിചൊല്ലുകൾ mlwikiquote https://ml.wikiquote.org/wiki/%E0%B4%AA%E0%B5%8D%E0%B4%B0%E0%B4%A7%E0%B4%BE%E0%B4%A8_%E0%B4%A4%E0%B4%BE%E0%B5%BE MediaWiki 1.47.0-wmf.24 first-letter മീഡിയ പ്രത്യേകം സംവാദം ഉപയോക്താവ് ഉപയോക്താവിന്റെ സംവാദം വിക്കിചൊല്ലുകൾ വിക്കിചൊല്ലുകൾ സംവാദം പ്രമാണം പ്രമാണത്തിന്റെ സംവാദം മീഡിയവിക്കി മീഡിയവിക്കി സംവാദം ഫലകം ഫലകത്തിന്റെ സംവാദം സഹായം സഹായത്തിന്റെ സംവാദം വർഗ്ഗം വർഗ്ഗത്തിന്റെ സംവാദം TimedText TimedText talk ഘടകം ഘടകത്തിന്റെ സംവാദം Event Event talk ലിയോ ടോൾസ്റ്റോയ് 0 4000 28011 24995 2026-10-24T01:14:16Z Kiran Gopi 624 28011 wikitext text/x-wiki [[പ്രമാണം:Ivan Nikolayevich Kramskoi - Portrait of Leo Tolstoy, 1873.jpg|thumb|200px|right]] '''ലിയോ നിക്കോളെവിച്ച്‌ ടോൾസ്റ്റോയ്‌''' ([[സെപ്റ്റംബർ 9]], 1828 - [[നവംബർ 20]], 1910) [[റഷ്യ|റഷ്യൻ]] എഴുത്തുകാരനും ചിന്തകനുമായിരുന്നു. യുദ്ധവും സമാധാനവും(War and Peace), അന്നാ കരേനിന എന്നീ നോവലുകളിലൂടെ അദ്ദേഹം പ്രശസ്തനായി. റഷ്യൻ ജീവിതത്തിന്റെ തനതായ ആവിഷ്കാരത്തിന്റേയും മുനുഷ്യജീവിതത്തിലേയും ചരിത്രത്തിലേയും പ്രശ്നങ്ങളോടുള്ള സമഗ്രമായ സമീപനത്തിന്റേയും പേരിൽ ടോൾസ്റ്റോയിയുടെ രചനകൾ ശ്രദ്ധിക്കപ്പെട്ടു. ഒരു ചിന്തകനെന്ന നിലയിൽ, അക്രമാരഹിത പ്രതിരോധമെന്ന ആശയത്തിൽ അദ്ദേഹം പ്രത്യേകം ഊന്നൽ നൽകി. അഹിംസാമാർഗ്ഗം പിന്തുടർന്ന [[മഹാത്മാ ഗാന്ധി]],[[മാർട്ടിൻ ലൂഥർ കിംഗ് ജൂനിയർ|മാർട്ടിൻ ലൂതർ കിംഗ്‌]] തുടങ്ങിയവർ, വലിയൊരളവോളം അദ്ദേഹത്തോട് ആശയപര മായി കടപ്പെട്ടിരിക്കുന്നു. ==ടോൾസ്റ്റോയ്‌' മൊഴികൾ== #എനിക്ക് ജീവിതത്തിൽ മൂന്നു കാര്യങ്ങളേ പ്രധാനപ്പെട്ടതായുള്ളൂ.അവ പുസ്തകങ്ങൾ മാത്രം #കല എന്നത് കരവിരുത് മാത്രമല്ല. അത് കലാകാരനുണ്ടായിട്ടുള്ള അനുഭവങ്ങളുടെ പ്രകടനമാണ്. #ലോകത്തിൽ മാറ്റങ്ങൾ വരണമെന്ന് ഏവരും ആഗ്രഹിക്കുന്നു. എന്നാൽ സ്വയം മാറ്റത്തിനു വിധേയനവാൻ ആരും തയ്യാറല്ല താനും #ചരിത്രകാരന്മാർ ബധിരന്മാരെ പോലെയാണ്. ആരും അവരോട് ഒന്നും ചോദിക്കുന്നില്ലെങ്കിലും അവർ ഉത്തരങ്ങൾ നൽകി കൊണ്ടേയിരിക്കും #കാലവും ക്ഷമയും ഇവരാണ് ഏറ്റവും ശകതരായ രണ്ട് യോദ്ധാക്കൽ #ബുദ്ധിമതികളായ സ്ത്രീകളുമായുള്ള സൗഹൃദം ഏതൊരു ചെറുപ്പക്കാരനും അത്യാവശ്യമായും ഉണ്ടായിരിക്കേണ്ടുന്നതാണ് # പരിപൂർണ്ണത അന്വേഷിക്കുന്നവൻ ഒരിക്കലും സംതൃപ്തനായിരിക്കില്ല. # നമ്മുടെ വികാരങ്ങൾ മറ്റൊരാൾക്ക് പറഞ്ഞു മനസ്സിലാക്കികൊടുക്കുക എന്നത് സാധ്യമാണോ? # ഒരു മനുഷ്യന്റെ മുതുകത്തു കയറി ഇരിക്കുകയാണു ഞാൻ, അയാളെ ശ്വാസം മുട്ടിക്കുകയാണു ഞാൻ, അയാളെക്കൊണ്ട് എന്നെ ചുമപ്പിക്കുകയാണു ഞാൻ, എന്നിട്ട് എന്നെത്തന്നെയും മറ്റുള്ളവരെയും ഞാൻ വിശ്വസിപ്പിക്കാൻ ശ്രമിക്കുകയാണ്‌, എനിക്കയാളുടെ കാര്യത്തിൽ വലിയ സങ്കടമുണ്ടെന്നും, ആ തലവിധിയിൽ നിന്ന് അയാളെ മോചിപ്പിക്കാൻ എനിക്കു സാദ്ധ്യമായതൊക്കെ ഞാൻ ചെയ്യുമെന്നും- എന്നു പറഞ്ഞാൽ, അയാളുടെ മുതുകത്തു നിന്നിറങ്ങുക എന്നതൊഴികെ. [[an:Leo Tolstoy]] [[arz:ليو تولستوى]] [[av:Лев Николаевич Толстой]] [[bat-smg:Levs Tuolstuos]] [[be-x-old:Леў Талстой]] [[bo:ཐོར་སི་ཐའེ།]] [[ckb:لێئۆ تۆلستۆی]] [[cv:Толстой Лев Николаевич]] [[ext:Leo Tolstoy]] [[fy:Lev Tolstoj]] [[gan:托爾斯泰]] [[gd:Leo Tolstoy]] [[hif:Leo Tolstoy]] [[io:Lev Tolstoy]] [[kaa:Lev Tolstoy]] [[lv:Ļevs Tolstojs]] [[mk:Лав Николаевич Толстој]] [[mn:Лев Толстой]] [[ms:Leo Tolstoy]] [[mwl:Liev Tolstói]] [[my:လီယိုတော်စတွိုင်း]] [[oc:Leon Tolstoi]] [[os:Толстой, Лев Николайы фырт]] [[pam:Leo Tolstoy]] [[pms:Lev Nicolaevic Tolstoj]] [[pnb:ٹالسٹائی]] [[ps:لېو نيكولايوويچ تولستوى]] [[rue:Лев Толстой]] [[sah:Лев Толстой]] [[scn:Liuni Tolstoi]] [[sw:Leo Tolstoy]] [[tg:Лев Николаевич Толстой]] [[tl:Leo Tolstoy]] [[war:Leo Tolstoy]] [[yi:לעא טאלסטוי]] [[yo:Leo Tolstoy]] [[zh-yue:托爾斯泰]] [[വർഗ്ഗം:വ്യക്തികൾ]] fw8mwbifvf26xckmg3mgo9rvsif17ft മുദ്രാവാക്യങ്ങൾ 0 5268 27985 18114 2026-10-24T00:50:58Z Kiran Gopi 624 27985 wikitext text/x-wiki *ശാസ്ത്രം സാമൂഹ്യവിപ്ലവത്തിനു -കേരള ശാസ്ത്ര സാഹിത്യ പരിഷത്ത് *മരം ഒരു വരം - വനം വന്യജീവി വകുപ്പ് *അമേരിക്കൻ മോഡൽ അറബിക്കടലിൽ -പുന്നപ്ര-വയലാർ സമരം *എല്ലാവർക്കും വിദ്യാഭ്യാസം, എല്ലാവർക്കും തൊഴിൽ - ഡി വൈ എഫ് ഐ *പഠിക്കുക...പോരാടുക, സ്വാതന്ത്ര്യം ജനാധിപത്യം സോഷ്യലിസം - എസ്.എഫ്.ഐ [[വർഗ്ഗം:വ്യവഹാരം]] mm1yvmaijexwspdlkg8c455wobx7cf4 27986 27985 2026-10-24T00:52:08Z Kiran Gopi 624 27986 wikitext text/x-wiki *ശാസ്ത്രം സാമൂഹ്യവിപ്ലവത്തിനു -കേരള ശാസ്ത്ര സാഹിത്യ പരിഷത്ത് *മരം ഒരു വരം - വനം വന്യജീവി വകുപ്പ് *അമേരിക്കൻ മോഡൽ അറബിക്കടലിൽ -പുന്നപ്ര-വയലാർ സമരം *എല്ലാവർക്കും വിദ്യാഭ്യാസം, എല്ലാവർക്കും തൊഴിൽ - ഡി വൈ എഫ് ഐ *പഠിക്കുക...പോരാടുക, സ്വാതന്ത്ര്യം ജനാധിപത്യം സോഷ്യലിസം - എസ്.എഫ്.ഐ [[വർഗ്ഗം:വ്യവഹാരം]] [[വർഗ്ഗം:വിപണനം]] ozah6s10ncuwnk8kzlrrxgxippei4h3 മംഗള നാർലിക്കർ 0 6886 28012 25173 2026-10-24T01:15:06Z Kiran Gopi 624 28012 wikitext text/x-wiki ഗണിതത്തിൽ ഗവേഷണം നടത്തിയ ഒരു വനിതയായിരുന്നു '''മംഗള നാർലിക്കർ'''(17 മെയ് 1943 – 17 ജൂലൈ 2023) . ഗവേഷണം നടത്തുന്നതിനോടൊപ്പം തന്നെ സാധാരണക്കാർക്കുവേണ്ടി ഗണിതത്തെപ്പറ്റി എഴുതുകയും മംഗള ചെയ്തിരുന്നു ==ഉദ്ധരണികൾ== *അതുവരെ, എൻ്റെ തിരഞ്ഞെടുപ്പുകൾ കാരണം ഞാൻ ഒരിക്കലും എൻ്റെ കരിയറിന് മുൻഗണന നൽകിയിരുന്നില്ല, എന്നാൽ ഇപ്പോൾ ഞാൻ രണ്ട് ലോകങ്ങൾ കൈകാര്യം ചെയ്യാനുള്ള കഠിനമായ തീരുമാനമെടുത്തു. ജയന്തും എൻ്റെ അമ്മായിയപ്പന്മാരും എല്ലായ്‌പ്പോഴും പിന്തുണച്ചിരുന്നതിനാൽ അവിടെയെങ്കിലും എനിക്ക് യുദ്ധം ചെയ്യേണ്ടി വന്നില്ല. ഇത് ബുദ്ധിമുട്ടാണെന്ന് എനിക്കറിയാമായിരുന്നു, പക്ഷേ ജോലി ചെയ്യാനും പിഎച്ച്ഡി ചെയ്യാനും ഞാൻ തീരുമാനിച്ചു ** [https://thebetterindia.com/250562/womens-day-dr-mangala-narlikar-mathematician-women-in-stem-science-india-gop94/ വാർത്ത - ഗോപി കരേല] *ഇതാണ് പെൺകുട്ടികളുടെ പ്രശ്നം...നിങ്ങൾ നന്നായി പഠിക്കും, ഉയർന്ന മാർക്ക് വാങ്ങും, വിവാഹശേഷം അതെല്ലാം ഉപേക്ഷിക്കും. ** [https://thebetterindia.com/250562/womens-day-dr-mangala-narlikar-mathematician-women-in-stem-science-india-gop94/ വാർത്ത - ഗോപി കരേല] *ഒരു ശുദ്ധ ഗണിതശാസ്ത്രജ്ഞനെ ശാസ്ത്രജ്ഞൻ എന്ന് വിളിക്കാമെങ്കിൽ മാത്രമേ എനിക്ക് എന്നെ ഒരു പാർട്ട് ടൈം ശാസ്ത്രജ്ഞൻ എന്ന് വിശേഷിപ്പിക്കാൻ കഴിയൂ. ** [https://theprint.in/theprint-profile/mangala-narlikar-mathematics/2692892/ വാർത്ത-ദി പ്രിന്റ്] == പുറത്തേക്കുള്ള കണ്ണികൾ == {{വിക്കിപീഡിയ}} [[വർഗ്ഗം:മരിച്ച വ്യക്തികൾ]] [[വർഗ്ഗം:സ്ത്രീകൾ]] a9n4x6lc2n8woqx14yy6313jqs17qig വർഗ്ഗം:മറഞ്ഞിരിക്കുന്ന വർഗ്ഗങ്ങൾ 14 7213 27990 26859 2026-10-24T01:07:45Z Kiran Gopi 624 27990 wikitext text/x-wiki {{Maintenance category}} To add a category to this category, add the [[mw:Magic words|magic word]] <nowiki>__HIDDENCAT__</nowiki>. [[വർഗ്ഗം:വിക്കിചൊല്ലുകൾ പരിപാലനം]] k0m89v2y3ymjhvgdt1c4474hn3xalos ഫലകം:Maintenance category 10 7214 27991 2020-05-13T07:58:25Z en>Dibbydib 0 Created page with "{{Mbox | name = name of the template | demospace = category | type = notice | image = [[File:Warning-icon.png|40px]] | style=padding:10px; | textstyle=CSS values | text = T..." 27991 wikitext text/x-wiki {{Mbox | name = name of the template | demospace = category | type = notice | image = [[File:Warning-icon.png|40px]] | style=padding:10px; | textstyle=CSS values | text = This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty. | small = left | plainlinks = no }} 6v57kow2n2woy7ka8422ex3n86twmbf 27992 27991 2020-05-13T08:14:11Z en>Dibbydib 0 27992 wikitext text/x-wiki {{Mbox | name = name of the template | demospace = category | type = notice | image = [[File:Warning-icon.png|40px]] | style=padding:10px; | textstyle=CSS values | text = {{#if:{{{1|empty}}}|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty.|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] and should not be deleted because it is empty.}} | small = left | plainlinks = no }} h6tbconz7zptfmthth784hxdudffct2 27993 27992 2020-05-13T08:15:50Z en>Dibbydib 0 27993 wikitext text/x-wiki {{Mbox | name = name of the template | demospace = category | type = notice | image = [[File:Warning-icon.png|40px]] | style=padding:10px; | textstyle=CSS values | text = {{#if:{{{1|}}}|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty.|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] and should not be deleted because it is empty.}} | small = left | plainlinks = no }} 41bj2f6leql7ricw5o62fblxd4jhqdd 27994 27993 2020-05-13T08:16:26Z en>Dibbydib 0 27994 wikitext text/x-wiki {{Mbox | name = name of the template | demospace = category | type = notice | image = [[File:Warning-icon.png|40px]] | style=padding:10px; | textstyle=CSS values | text = {{#if:{{{1|}}}|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] and should not be deleted because it is empty.|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty.}} | small = left | plainlinks = no }} qz864d0pdq1uri9aluy7geeq1zm3wg6 27995 27994 2020-05-13T09:32:16Z en>Dibbydib 0 27995 wikitext text/x-wiki {{Mbox | name = name of the template | demospace = category | type = notice | image = [[File:Warning-icon.png|40px]] | style=padding:10px; | textstyle=CSS values | text = {{#if:{{{1|}}}|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] and should not be deleted because it is empty.|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty.}} | small = left | plainlinks = no }} <noinclude>{{Doc}}</noinclude> he8ghyhz3wc912a2lk6s6xfrwwuoglt 27996 27995 2020-05-13T09:37:22Z en>Dibbydib 0 27996 wikitext text/x-wiki {{Mbox | name = name of the template | demospace = category | type = notice | image = [[File:Warning-icon.png|40px]] | style=padding:10px; | textstyle=CSS values | text = {{#if:{{{1|}}}|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] and should not be deleted because it is empty.|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty.}} | small = left | plainlinks = no }} <noinclude>{{Doc}}[[Category:Wikiquote maintenance templates]]</noinclude> cpiikvq57u6icjv37vtlkgd2b9d7jin 27997 27996 2021-01-18T18:18:45Z en>Tacsipacsi 0 use {{[[template:cmbox|cmbox]]}} to ensure the same layout here as on the category pages 27997 wikitext text/x-wiki {{cmbox | name = name of the template | demospace = category | type = notice | image = [[File:Warning-icon.png|40px]] | style=padding:10px; | textstyle=CSS values | text = {{#if:{{{1|}}}|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] and should not be deleted because it is empty.|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty.}} | small = left | plainlinks = no }}<noinclude>{{Doc}}[[Category:Wikiquote maintenance templates]]</noinclude> p7bdl2ifgv1gqj6zk1lygpbi7ufwei8 27998 27997 2021-01-18T18:22:30Z en>Tacsipacsi 0 add __EXPECTUNUSEDCATEGORY__ so that these categories don’t show up on [[Special:UnusedCategories]], remove unused/garbage parameters 27998 wikitext text/x-wiki {{cmbox | type = notice | image = [[File:Warning-icon.png|40px]] | text = {{#if:{{{1|}}}|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] and should not be deleted because it is empty.|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty.}} }}__EXPECTUNUSEDCATEGORY__<noinclude>{{Doc}}[[Category:Wikiquote maintenance templates]]</noinclude> n7lkio1940uvyoglxgro8hg5arqfblw 27999 26861 2026-10-24T01:09:02Z Kiran Gopi 624 [[:en:Template:Maintenance_category]] എന്നതിൽ നിന്ന് 8 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 26860 wikitext text/x-wiki {{cmbox | type = notice | image = [[File:Emojione 26A0.svg|40px]] | text = {{#if:{{{1|}}}|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] and should not be deleted because it is empty.|This page is a [[:Category:Wikiquote maintenance|'''maintenance category''']] for Wikiquote and should not be deleted even if it is empty.}} }}__EXPECTUNUSEDCATEGORY__<noinclude>{{Doc}}[[Category:Wikiquote maintenance templates]]</noinclude> surc7m3rtgvcusn7s1qgiwpyrdopgio ഭവിത മണ്ഡാവ 0 7364 27972 2026-10-23T17:58:32Z SijiR 5558 #SheSaid #100wikiquotedays 27972 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനൽ' (Chanel)-ന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. dp8eqz1uqk2qq30d43zr4ldp9gck1sj 27973 27972 2026-10-23T17:59:09Z SijiR 5558 #SheSaid 27973 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനൽ' (Chanel)-ന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == junf4tq5pslxh1uslc74fuipps9cb22 27974 27973 2026-10-23T18:34:12Z SijiR 5558 #SheSaid 27974 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == == പുറത്തേക്കുള്ള കണ്ണികൾ == 9nxtq9g5sybsa05ed08u88geze2nnog 27975 27974 2026-10-23T18:34:45Z SijiR 5558 #SheSaid 27975 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] 20ai9qwcjdwcp1gbur8e9un3hgspvq0 27976 27975 2026-10-23T18:38:17Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27976 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] to8uwyqqlpogh9xqf4kywaq3mgdtffv 27977 27976 2026-10-23T18:40:40Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27977 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. **"ചരിത്രം സൃഷ്ടിച്ച, തന്റെ വിനോദങ്ങളെ പരമാവധി പ്രയോജനപ്പെടുത്തുന്ന ചാനൽ മോഡലായ ഭവിത മണ്ഡാവയെ പരിചയപ്പെടൂ." - ഡെയ്‌സ്ഡ്. 10 ഡിസംബർ 2025. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] 8fywigyt9m9q978n1bwnuqqe6c29uwy 27978 27977 2026-10-23T18:41:50Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27978 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. **"[https://www.dazeddigital.com/fashion/article/69261/1/bhavitha-mandava-first-ever-indian-model-opened-chanel-metiers-dart-show ചരിത്രം സൃഷ്ടിച്ച, തന്റെ വിനോദങ്ങളെ പരമാവധി പ്രയോജനപ്പെടുത്തുന്ന ചാനൽ മോഡലായ ഭവിത മണ്ഡാവയെ പരിചയപ്പെടൂ."] - ഡെയ്‌സ്ഡ്. 10 ഡിസംബർ 2025. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] o5tr29ssnq23j3877cp9qeorljjchov 27979 27978 2026-10-23T18:45:28Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27979 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. **"[https://www.dazeddigital.com/fashion/article/69261/1/bhavitha-mandava-first-ever-indian-model-opened-chanel-metiers-dart-show ചരിത്രം സൃഷ്ടിച്ച, തന്റെ വിനോദങ്ങളെ പരമാവധി പ്രയോജനപ്പെടുത്തുന്ന ചാനൽ മോഡലായ ഭവിത മണ്ഡാവയെ പരിചയപ്പെടൂ."] - ഡെയ്‌സ്ഡ്. 10 ഡിസംബർ 2025. *ചാനൽ ഷോയിൽ തുടക്കം കുറിച്ചത് എന്നെ സംബന്ധിച്ചിടത്തോളം വളരെ വ്യക്തിപരമായ ഒരു കാര്യമായിരുന്നു; എന്നാൽ പെട്ടെന്നത് ഞാൻ ഒട്ടും പ്രതീക്ഷിക്കാത്ത വിധത്തിൽ ഒരു പ്രതീകാത്മക തലത്തിലേക്ക് ഉയർന്നു. പാശ്ചാത്യലോകത്ത്, 'സൗന്ദര്യം' എന്ന സങ്കൽപ്പത്തിൽ ആരൊക്കെ ഉൾപ്പെടുന്നു എന്ന ചോദ്യവും, ഇന്ത്യൻ സ്ത്രീകൾക്ക് പരമ്പരാഗതമായ അർത്ഥത്തിൽ 'സുന്ദരികൾ' ആയിരിക്കാൻ അർഹതയുണ്ടോ എന്ന ചിന്തയും ഇത് ഉയർത്തിക്കൊണ്ടു വന്നു. ഇന്ത്യയിൽ, ചർമ്മനിറത്തിന്റെ പേരിൽ വിവേചനം കാണിക്കുന്ന പ്രവണത വളരെ ആഴത്തിൽ വേരോടിയ ഒന്നാണ്. വെളുത്ത നിറമുള്ള ചർമ്മത്തെയാണ് പലപ്പോഴും 'സാധാരണ' അല്ലെങ്കിൽ 'അടിസ്ഥാന' സൗന്ദര്യമായി കണക്കാക്കിപ്പോരുന്നത് എന്നതുകൊണ്ട്, എന്നെ കണ്ടപ്പോൾ 'തെരുവിലുള്ള ഏതൊരു പെൺകുട്ടിയെയും പോലെ' ഇരിക്കുന്നു എന്ന് ആളുകൾ പറഞ്ഞു. ഇത് എന്നെക്കുറിച്ചുള്ള കാര്യമല്ല; മറിച്ച്, ഒരു സംസ്കാരം തന്നെത്തന്നെ പുനർനിർവചിക്കാൻ ശ്രമിക്കുന്നതാണ് എന്ന് എനിക്ക് തോന്നുന്നു. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] n9tg9jdxz1w63as11xrza0gqelc6v42 27980 27979 2026-10-23T18:48:13Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27980 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. **"[https://www.dazeddigital.com/fashion/article/69261/1/bhavitha-mandava-first-ever-indian-model-opened-chanel-metiers-dart-show ചരിത്രം സൃഷ്ടിച്ച, തന്റെ വിനോദങ്ങളെ പരമാവധി പ്രയോജനപ്പെടുത്തുന്ന ചാനൽ മോഡലായ ഭവിത മണ്ഡാവയെ പരിചയപ്പെടൂ."] - ഡെയ്‌സ്ഡ്. 10 ഡിസംബർ 2025. *ചാനൽ ഷോയിൽ തുടക്കം കുറിച്ചത് എന്നെ സംബന്ധിച്ചിടത്തോളം വളരെ വ്യക്തിപരമായ ഒരു കാര്യമായിരുന്നു; എന്നാൽ പെട്ടെന്നത് ഞാൻ ഒട്ടും പ്രതീക്ഷിക്കാത്ത വിധത്തിൽ ഒരു പ്രതീകാത്മക തലത്തിലേക്ക് ഉയർന്നു. പാശ്ചാത്യലോകത്ത്, 'സൗന്ദര്യം' എന്ന സങ്കൽപ്പത്തിൽ ആരൊക്കെ ഉൾപ്പെടുന്നു എന്ന ചോദ്യവും, ഇന്ത്യൻ സ്ത്രീകൾക്ക് പരമ്പരാഗതമായ അർത്ഥത്തിൽ 'സുന്ദരികൾ' ആയിരിക്കാൻ അർഹതയുണ്ടോ എന്ന ചിന്തയും ഇത് ഉയർത്തിക്കൊണ്ടു വന്നു. ഇന്ത്യയിൽ, ചർമ്മനിറത്തിന്റെ പേരിൽ വിവേചനം കാണിക്കുന്ന പ്രവണത വളരെ ആഴത്തിൽ വേരോടിയ ഒന്നാണ്. വെളുത്ത നിറമുള്ള ചർമ്മത്തെയാണ് പലപ്പോഴും 'സാധാരണ' അല്ലെങ്കിൽ 'അടിസ്ഥാന' സൗന്ദര്യമായി കണക്കാക്കിപ്പോരുന്നത് എന്നതുകൊണ്ട്, എന്നെ കണ്ടപ്പോൾ 'തെരുവിലുള്ള ഏതൊരു പെൺകുട്ടിയെയും പോലെ' ഇരിക്കുന്നു എന്ന് ആളുകൾ പറഞ്ഞു. ഇത് എന്നെക്കുറിച്ചുള്ള കാര്യമല്ല; മറിച്ച്, ഒരു സംസ്കാരം തന്നെത്തന്നെ പുനർനിർവചിക്കാൻ ശ്രമിക്കുന്നതാണ് എന്ന് എനിക്ക് തോന്നുന്നു. **നദി, ചിയോമ (11 ഫെബ്രുവരി 2026). "'ആർക്കാണ് ഇനി 9 മുതൽ 5 വരെയുള്ള ജോലിയിലേക്ക് മടങ്ങാൻ കഴിയുക?' - ഫാഷൻ ലോകത്തെ ഉദിച്ചുയരുന്ന താരം ഭവിത മണ്ഡാവ നയിക്കുന്നത് ഒരു യക്ഷിക്കഥയിലെന്നപോലെയുള്ള ജീവിതം". ബ്രിട്ടീഷ് വോഗ്. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] 15y35ng3r13ndrr2ixf43rsajqj3gy8 27981 27980 2026-10-23T18:49:15Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27981 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. **"[https://www.dazeddigital.com/fashion/article/69261/1/bhavitha-mandava-first-ever-indian-model-opened-chanel-metiers-dart-show ചരിത്രം സൃഷ്ടിച്ച, തന്റെ വിനോദങ്ങളെ പരമാവധി പ്രയോജനപ്പെടുത്തുന്ന ചാനൽ മോഡലായ ഭവിത മണ്ഡാവയെ പരിചയപ്പെടൂ."] - ഡെയ്‌സ്ഡ്. 10 ഡിസംബർ 2025. *ചാനൽ ഷോയിൽ തുടക്കം കുറിച്ചത് എന്നെ സംബന്ധിച്ചിടത്തോളം വളരെ വ്യക്തിപരമായ ഒരു കാര്യമായിരുന്നു; എന്നാൽ പെട്ടെന്നത് ഞാൻ ഒട്ടും പ്രതീക്ഷിക്കാത്ത വിധത്തിൽ ഒരു പ്രതീകാത്മക തലത്തിലേക്ക് ഉയർന്നു. പാശ്ചാത്യലോകത്ത്, 'സൗന്ദര്യം' എന്ന സങ്കൽപ്പത്തിൽ ആരൊക്കെ ഉൾപ്പെടുന്നു എന്ന ചോദ്യവും, ഇന്ത്യൻ സ്ത്രീകൾക്ക് പരമ്പരാഗതമായ അർത്ഥത്തിൽ 'സുന്ദരികൾ' ആയിരിക്കാൻ അർഹതയുണ്ടോ എന്ന ചിന്തയും ഇത് ഉയർത്തിക്കൊണ്ടു വന്നു. ഇന്ത്യയിൽ, ചർമ്മനിറത്തിന്റെ പേരിൽ വിവേചനം കാണിക്കുന്ന പ്രവണത വളരെ ആഴത്തിൽ വേരോടിയ ഒന്നാണ്. വെളുത്ത നിറമുള്ള ചർമ്മത്തെയാണ് പലപ്പോഴും 'സാധാരണ' അല്ലെങ്കിൽ 'അടിസ്ഥാന' സൗന്ദര്യമായി കണക്കാക്കിപ്പോരുന്നത് എന്നതുകൊണ്ട്, എന്നെ കണ്ടപ്പോൾ 'തെരുവിലുള്ള ഏതൊരു പെൺകുട്ടിയെയും പോലെ' ഇരിക്കുന്നു എന്ന് ആളുകൾ പറഞ്ഞു. ഇത് എന്നെക്കുറിച്ചുള്ള കാര്യമല്ല; മറിച്ച്, ഒരു സംസ്കാരം തന്നെത്തന്നെ പുനർനിർവചിക്കാൻ ശ്രമിക്കുന്നതാണ് എന്ന് എനിക്ക് തോന്നുന്നു. **നദി, ചിയോമ (11 ഫെബ്രുവരി 2026). [https://www.vogue.co.uk/article/bhavitha-mandava-british-vogue-interview "'ആർക്കാണ് ഇനി 9 മുതൽ 5 വരെയുള്ള ജോലിയിലേക്ക് മടങ്ങാൻ കഴിയുക?' - ഫാഷൻ ലോകത്തെ ഉദിച്ചുയരുന്ന താരം ഭവിത മണ്ഡാവ നയിക്കുന്നത് ഒരു യക്ഷിക്കഥയിലെന്നപോലെയുള്ള ജീവിതം".] ബ്രിട്ടീഷ് വോഗ്. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] hc9vuu1zjidkbuo8ykjkypnn629kv45 27982 27981 2026-10-23T18:51:48Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27982 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. **"[https://www.dazeddigital.com/fashion/article/69261/1/bhavitha-mandava-first-ever-indian-model-opened-chanel-metiers-dart-show ചരിത്രം സൃഷ്ടിച്ച, തന്റെ വിനോദങ്ങളെ പരമാവധി പ്രയോജനപ്പെടുത്തുന്ന ചാനൽ മോഡലായ ഭവിത മണ്ഡാവയെ പരിചയപ്പെടൂ."] - ഡെയ്‌സ്ഡ്. 10 ഡിസംബർ 2025. *ചാനൽ ഷോയിൽ തുടക്കം കുറിച്ചത് എന്നെ സംബന്ധിച്ചിടത്തോളം വളരെ വ്യക്തിപരമായ ഒരു കാര്യമായിരുന്നു; എന്നാൽ പെട്ടെന്നത് ഞാൻ ഒട്ടും പ്രതീക്ഷിക്കാത്ത വിധത്തിൽ ഒരു പ്രതീകാത്മക തലത്തിലേക്ക് ഉയർന്നു. പാശ്ചാത്യലോകത്ത്, 'സൗന്ദര്യം' എന്ന സങ്കൽപ്പത്തിൽ ആരൊക്കെ ഉൾപ്പെടുന്നു എന്ന ചോദ്യവും, ഇന്ത്യൻ സ്ത്രീകൾക്ക് പരമ്പരാഗതമായ അർത്ഥത്തിൽ 'സുന്ദരികൾ' ആയിരിക്കാൻ അർഹതയുണ്ടോ എന്ന ചിന്തയും ഇത് ഉയർത്തിക്കൊണ്ടു വന്നു. ഇന്ത്യയിൽ, ചർമ്മനിറത്തിന്റെ പേരിൽ വിവേചനം കാണിക്കുന്ന പ്രവണത വളരെ ആഴത്തിൽ വേരോടിയ ഒന്നാണ്. വെളുത്ത നിറമുള്ള ചർമ്മത്തെയാണ് പലപ്പോഴും 'സാധാരണ' അല്ലെങ്കിൽ 'അടിസ്ഥാന' സൗന്ദര്യമായി കണക്കാക്കിപ്പോരുന്നത് എന്നതുകൊണ്ട്, എന്നെ കണ്ടപ്പോൾ 'തെരുവിലുള്ള ഏതൊരു പെൺകുട്ടിയെയും പോലെ' ഇരിക്കുന്നു എന്ന് ആളുകൾ പറഞ്ഞു. ഇത് എന്നെക്കുറിച്ചുള്ള കാര്യമല്ല; മറിച്ച്, ഒരു സംസ്കാരം തന്നെത്തന്നെ പുനർനിർവചിക്കാൻ ശ്രമിക്കുന്നതാണ് എന്ന് എനിക്ക് തോന്നുന്നു. **നദി, ചിയോമ (11 ഫെബ്രുവരി 2026). [https://www.vogue.co.uk/article/bhavitha-mandava-british-vogue-interview "'ആർക്കാണ് ഇനി 9 മുതൽ 5 വരെയുള്ള ജോലിയിലേക്ക് മടങ്ങാൻ കഴിയുക?' - ഫാഷൻ ലോകത്തെ ഉദിച്ചുയരുന്ന താരം ഭവിത മണ്ഡാവ നയിക്കുന്നത് ഒരു യക്ഷിക്കഥയിലെന്നപോലെയുള്ള ജീവിതം".] ബ്രിട്ടീഷ് വോഗ്. *ചാനൽ ഷോയിൽ ഞാൻ പങ്കെടുത്തത്, 'ആരാണ് സുന്ദരി' എന്നതിനെക്കുറിച്ചുള്ള ഒരു ചർച്ചയ്ക്ക് തുടക്കമിട്ടു. ഇന്റർനെറ്റ് ഇക്കാര്യത്തിൽ രണ്ടായി വിഭജിക്കപ്പെട്ടു; അതിലൊരു വിഭാഗത്തിന്, ഇന്ത്യൻ സ്ത്രീകൾ സുന്ദരികളാണെന്ന് പോലും അറിയില്ലായിരുന്നു. ഞാൻ കേട്ടിട്ടുള്ളതിൽ വെച്ച് ഏറ്റവും വിചിത്രമായ കാര്യമായിരുന്നു അത്. തീർച്ചയായും, വംശീയമായ നിരവധി അഭിപ്രായങ്ങൾ ഉയർന്നു വരും എന്ന് എനിക്കറിയാമായിരുന്നു. എന്നാൽ, "അയ്യോ, ഇന്ത്യൻ സ്ത്രീകൾ ശരിക്കും സുന്ദരികളാണല്ലോ!" എന്ന് അവർ അത്ഭുതത്തോടെ പറയുന്നത് കേട്ടപ്പോൾ, അതൊരു അഭിനന്ദനമായി എനിക്ക് തോന്നിയില്ല. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] 99dphc6n5zf8ep0kvf95kvmtc7ynk7f 27983 27982 2026-10-23T18:54:16Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27983 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. **"[https://www.dazeddigital.com/fashion/article/69261/1/bhavitha-mandava-first-ever-indian-model-opened-chanel-metiers-dart-show ചരിത്രം സൃഷ്ടിച്ച, തന്റെ വിനോദങ്ങളെ പരമാവധി പ്രയോജനപ്പെടുത്തുന്ന ചാനൽ മോഡലായ ഭവിത മണ്ഡാവയെ പരിചയപ്പെടൂ."] - ഡെയ്‌സ്ഡ്. 10 ഡിസംബർ 2025. *ചാനൽ ഷോയിൽ തുടക്കം കുറിച്ചത് എന്നെ സംബന്ധിച്ചിടത്തോളം വളരെ വ്യക്തിപരമായ ഒരു കാര്യമായിരുന്നു; എന്നാൽ പെട്ടെന്നത് ഞാൻ ഒട്ടും പ്രതീക്ഷിക്കാത്ത വിധത്തിൽ ഒരു പ്രതീകാത്മക തലത്തിലേക്ക് ഉയർന്നു. പാശ്ചാത്യലോകത്ത്, 'സൗന്ദര്യം' എന്ന സങ്കൽപ്പത്തിൽ ആരൊക്കെ ഉൾപ്പെടുന്നു എന്ന ചോദ്യവും, ഇന്ത്യൻ സ്ത്രീകൾക്ക് പരമ്പരാഗതമായ അർത്ഥത്തിൽ 'സുന്ദരികൾ' ആയിരിക്കാൻ അർഹതയുണ്ടോ എന്ന ചിന്തയും ഇത് ഉയർത്തിക്കൊണ്ടു വന്നു. ഇന്ത്യയിൽ, ചർമ്മനിറത്തിന്റെ പേരിൽ വിവേചനം കാണിക്കുന്ന പ്രവണത വളരെ ആഴത്തിൽ വേരോടിയ ഒന്നാണ്. വെളുത്ത നിറമുള്ള ചർമ്മത്തെയാണ് പലപ്പോഴും 'സാധാരണ' അല്ലെങ്കിൽ 'അടിസ്ഥാന' സൗന്ദര്യമായി കണക്കാക്കിപ്പോരുന്നത് എന്നതുകൊണ്ട്, എന്നെ കണ്ടപ്പോൾ 'തെരുവിലുള്ള ഏതൊരു പെൺകുട്ടിയെയും പോലെ' ഇരിക്കുന്നു എന്ന് ആളുകൾ പറഞ്ഞു. ഇത് എന്നെക്കുറിച്ചുള്ള കാര്യമല്ല; മറിച്ച്, ഒരു സംസ്കാരം തന്നെത്തന്നെ പുനർനിർവചിക്കാൻ ശ്രമിക്കുന്നതാണ് എന്ന് എനിക്ക് തോന്നുന്നു. **നദി, ചിയോമ (11 ഫെബ്രുവരി 2026). [https://www.vogue.co.uk/article/bhavitha-mandava-british-vogue-interview "'ആർക്കാണ് ഇനി 9 മുതൽ 5 വരെയുള്ള ജോലിയിലേക്ക് മടങ്ങാൻ കഴിയുക?' - ഫാഷൻ ലോകത്തെ ഉദിച്ചുയരുന്ന താരം ഭവിത മണ്ഡാവ നയിക്കുന്നത് ഒരു യക്ഷിക്കഥയിലെന്നപോലെയുള്ള ജീവിതം".] ബ്രിട്ടീഷ് വോഗ്. *ചാനൽ ഷോയിൽ ഞാൻ പങ്കെടുത്തത്, 'ആരാണ് സുന്ദരി' എന്നതിനെക്കുറിച്ചുള്ള ഒരു ചർച്ചയ്ക്ക് തുടക്കമിട്ടു. ഇന്റർനെറ്റ് ഇക്കാര്യത്തിൽ രണ്ടായി വിഭജിക്കപ്പെട്ടു; അതിലൊരു വിഭാഗത്തിന്, ഇന്ത്യൻ സ്ത്രീകൾ സുന്ദരികളാണെന്ന് പോലും അറിയില്ലായിരുന്നു. ഞാൻ കേട്ടിട്ടുള്ളതിൽ വെച്ച് ഏറ്റവും വിചിത്രമായ കാര്യമായിരുന്നു അത്. തീർച്ചയായും, വംശീയമായ നിരവധി അഭിപ്രായങ്ങൾ ഉയർന്നു വരും എന്ന് എനിക്കറിയാമായിരുന്നു. എന്നാൽ, "അയ്യോ, ഇന്ത്യൻ സ്ത്രീകൾ ശരിക്കും സുന്ദരികളാണല്ലോ!" എന്ന് അവർ അത്ഭുതത്തോടെ പറയുന്നത് കേട്ടപ്പോൾ, അതൊരു അഭിനന്ദനമായി എനിക്ക് തോന്നിയില്ല. **ചൗധരി, ശുഭാംഗി (13 ഫെബ്രുവരി 2016). "'ഡസ്‌കി സ്കിൻ ടോൺ സ്വീകരിക്കാൻ കഴിയില്ല': ചാനൽ സ്റ്റാർ ഭവിത മണ്ഡാവ ഓൺ ഇൻഡ്യസ് കളറിസം".ദി അമേരിക്കൻ ബസാർ. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] e40u7vgb7xkhn8tzk4s2ii93p3q47bk 27984 27983 2026-10-23T18:55:57Z SijiR 5558 /* ഉദ്ധരണികൾ */ #SheSaid 27984 wikitext text/x-wiki ഭവിത മണ്ഡാവ (ജനനം: 2000 ഫെബ്രുവരി 3) ഒരു ഇന്ത്യൻ ഫാഷൻ മോഡലാണ്. 'മെറ്റിയേഴ്സ് ഡി ആർട്ട്' 2026 ഷോയിൽ 'ചാനലിന് വേണ്ടി ഒരു ഷോയ്ക്ക് തുടക്കമിടുന്ന ആദ്യ ഇന്ത്യൻ വനിതയായി മാറിയതോടെ, 2025-ൽ അവർക്ക് ആഗോളതലത്തിൽ അംഗീകാരം ലഭിച്ചു. == ഉദ്ധരണികൾ == *ഫാഷൻ രംഗത്ത് തവിട്ടുനിറമുള്ളവരുടെ പ്രാതിനിധ്യം കുറവാണ്. കാസ്റ്റിംഗുകൾക്കായി ക്യൂവിൽ നിൽക്കുമ്പോൾ, മറ്റൊരു തവിട്ടുനിറമുള്ള മോഡലിനെ കാണുമ്പോൾ ഞങ്ങൾ പരസ്പരം നോക്കും; ഞങ്ങളിൽ ഒരാൾക്ക് മാത്രമേ ഈ അവസരം ലഭിക്കൂ എന്ന് ഞങ്ങൾക്ക് അപ്പോൾത്തന്നെ മനസ്സിലാകും. എന്നാൽ ചാനലിൽ സ്ഥിതി വ്യത്യസ്തമായിരുന്നു. മാത്യു എല്ലാവർക്കും ഇടം നൽകി. **"[https://www.dazeddigital.com/fashion/article/69261/1/bhavitha-mandava-first-ever-indian-model-opened-chanel-metiers-dart-show ചരിത്രം സൃഷ്ടിച്ച, തന്റെ വിനോദങ്ങളെ പരമാവധി പ്രയോജനപ്പെടുത്തുന്ന ചാനൽ മോഡലായ ഭവിത മണ്ഡാവയെ പരിചയപ്പെടൂ."] - ഡെയ്‌സ്ഡ്. 10 ഡിസംബർ 2025. *ചാനൽ ഷോയിൽ തുടക്കം കുറിച്ചത് എന്നെ സംബന്ധിച്ചിടത്തോളം വളരെ വ്യക്തിപരമായ ഒരു കാര്യമായിരുന്നു; എന്നാൽ പെട്ടെന്നത് ഞാൻ ഒട്ടും പ്രതീക്ഷിക്കാത്ത വിധത്തിൽ ഒരു പ്രതീകാത്മക തലത്തിലേക്ക് ഉയർന്നു. പാശ്ചാത്യലോകത്ത്, 'സൗന്ദര്യം' എന്ന സങ്കൽപ്പത്തിൽ ആരൊക്കെ ഉൾപ്പെടുന്നു എന്ന ചോദ്യവും, ഇന്ത്യൻ സ്ത്രീകൾക്ക് പരമ്പരാഗതമായ അർത്ഥത്തിൽ 'സുന്ദരികൾ' ആയിരിക്കാൻ അർഹതയുണ്ടോ എന്ന ചിന്തയും ഇത് ഉയർത്തിക്കൊണ്ടു വന്നു. ഇന്ത്യയിൽ, ചർമ്മനിറത്തിന്റെ പേരിൽ വിവേചനം കാണിക്കുന്ന പ്രവണത വളരെ ആഴത്തിൽ വേരോടിയ ഒന്നാണ്. വെളുത്ത നിറമുള്ള ചർമ്മത്തെയാണ് പലപ്പോഴും 'സാധാരണ' അല്ലെങ്കിൽ 'അടിസ്ഥാന' സൗന്ദര്യമായി കണക്കാക്കിപ്പോരുന്നത് എന്നതുകൊണ്ട്, എന്നെ കണ്ടപ്പോൾ 'തെരുവിലുള്ള ഏതൊരു പെൺകുട്ടിയെയും പോലെ' ഇരിക്കുന്നു എന്ന് ആളുകൾ പറഞ്ഞു. ഇത് എന്നെക്കുറിച്ചുള്ള കാര്യമല്ല; മറിച്ച്, ഒരു സംസ്കാരം തന്നെത്തന്നെ പുനർനിർവചിക്കാൻ ശ്രമിക്കുന്നതാണ് എന്ന് എനിക്ക് തോന്നുന്നു. **നദി, ചിയോമ (11 ഫെബ്രുവരി 2026). [https://www.vogue.co.uk/article/bhavitha-mandava-british-vogue-interview "'ആർക്കാണ് ഇനി 9 മുതൽ 5 വരെയുള്ള ജോലിയിലേക്ക് മടങ്ങാൻ കഴിയുക?' - ഫാഷൻ ലോകത്തെ ഉദിച്ചുയരുന്ന താരം ഭവിത മണ്ഡാവ നയിക്കുന്നത് ഒരു യക്ഷിക്കഥയിലെന്നപോലെയുള്ള ജീവിതം".] ബ്രിട്ടീഷ് വോഗ്. *ചാനൽ ഷോയിൽ ഞാൻ പങ്കെടുത്തത്, 'ആരാണ് സുന്ദരി' എന്നതിനെക്കുറിച്ചുള്ള ഒരു ചർച്ചയ്ക്ക് തുടക്കമിട്ടു. ഇന്റർനെറ്റ് ഇക്കാര്യത്തിൽ രണ്ടായി വിഭജിക്കപ്പെട്ടു; അതിലൊരു വിഭാഗത്തിന്, ഇന്ത്യൻ സ്ത്രീകൾ സുന്ദരികളാണെന്ന് പോലും അറിയില്ലായിരുന്നു. ഞാൻ കേട്ടിട്ടുള്ളതിൽ വെച്ച് ഏറ്റവും വിചിത്രമായ കാര്യമായിരുന്നു അത്. തീർച്ചയായും, വംശീയമായ നിരവധി അഭിപ്രായങ്ങൾ ഉയർന്നു വരും എന്ന് എനിക്കറിയാമായിരുന്നു. എന്നാൽ, "അയ്യോ, ഇന്ത്യൻ സ്ത്രീകൾ ശരിക്കും സുന്ദരികളാണല്ലോ!" എന്ന് അവർ അത്ഭുതത്തോടെ പറയുന്നത് കേട്ടപ്പോൾ, അതൊരു അഭിനന്ദനമായി എനിക്ക് തോന്നിയില്ല. **ചൗധരി, ശുഭാംഗി (13 ഫെബ്രുവരി 2016). "[https://americanbazaaronline.com/2026/02/13/cannot-accept-dusky-skin-tone-chanel-star-bhavitha-mandava-on-indias-colorism/ 'ഡസ്‌കി സ്കിൻ ടോൺ സ്വീകരിക്കാൻ കഴിയില്ല': ചാനൽ സ്റ്റാർ ഭവിത മണ്ഡാവ ഓൺ ഇൻഡ്യസ് കളറിസം".]ദി അമേരിക്കൻ ബസാർ. == പുറത്തേക്കുള്ള കണ്ണികൾ == [[വർഗ്ഗം:സ്ത്രീകൾ]] 3r4953gq7wg665m9v9e4bj1w20qnklx വർഗ്ഗം:വിപണനം 14 7365 27987 2026-10-24T00:52:32Z Kiran Gopi 624 '[[വർഗ്ഗം:വാണിജ്യം]]' താൾ സൃഷ്ടിച്ചിരിക്കുന്നു 27987 wikitext text/x-wiki [[വർഗ്ഗം:വാണിജ്യം]] md910r2sdke4s6cs4xaykcqzidw6ooh വർഗ്ഗം:വിക്കി ചൊല്ലുകൾ യന്ത്രങ്ങൾ 14 7366 27988 2026-10-24T01:04:02Z Kiran Gopi 624 '[[വർഗ്ഗം:വിക്കിചൊല്ലുകൾ പരിപാലനം]]' താൾ സൃഷ്ടിച്ചിരിക്കുന്നു 27988 wikitext text/x-wiki [[വർഗ്ഗം:വിക്കിചൊല്ലുകൾ പരിപാലനം]] gnrumu56w6v99nlb3w04tthc1br4hf9 വർഗ്ഗം:സൂചികാവത്കരിക്കപ്പെടാത്ത താളുകൾ 14 7367 27989 2026-10-24T01:06:21Z Kiran Gopi 624 '[[വർഗ്ഗം:വിക്കിചൊല്ലുകൾ പരിപാലനം]] [[വർഗ്ഗം:മറഞ്ഞിരിക്കുന്ന വർഗ്ഗങ്ങൾ]]' താൾ സൃഷ്ടിച്ചിരിക്കുന്നു 27989 wikitext text/x-wiki [[വർഗ്ഗം:വിക്കിചൊല്ലുകൾ പരിപാലനം]] [[വർഗ്ഗം:മറഞ്ഞിരിക്കുന്ന വർഗ്ഗങ്ങൾ]] 2slyu6hut7953kw3bxd2v0gu6nm1t9w 28009 27989 2026-10-24T01:11:04Z Kiran Gopi 624 28009 wikitext text/x-wiki {{Maintenance category}} __HIDDENCAT__ [[വർഗ്ഗം:വിക്കിചൊല്ലുകൾ പരിപാലനം]] 9cyvx3f56dkkrjjykiog9vzebqmx4ge ഫലകം:Doc 10 7368 28000 2007-07-04T09:46:34Z wikidata>Patrick 0 Redirect to [[Template:Documentation]] 28000 wikitext text/x-wiki #redirect [[Template:Documentation]] 0h49uabfhaeo9mrdbcrfaps8q3fhem8 28001 28000 2012-11-01T23:21:20Z wikidata>Ajraddatz 0 1 revision from [[:meta:Template:Doc]] 28000 wikitext text/x-wiki #redirect [[Template:Documentation]] 0h49uabfhaeo9mrdbcrfaps8q3fhem8 28002 28001 2018-06-07T23:46:36Z 68.119.131.236 Removed redirect to [[Template:Documentation]] 28002 wikitext text/x-wiki {{IPA|}}#redirect [[Template:Documentation]] p2e9ag81gfcehrtdvs4lwuwyhmqdfvs 28003 28002 2018-06-08T20:51:01Z wikidata>NicoScribe 0 Reverted edits by [[Special:Contributions/68.119.131.236|68.119.131.236]] ([[User talk:68.119.131.236|talk]]) to last revision by [[:User:Ajraddatz|Ajraddatz]] 28003 wikitext text/x-wiki #redirect [[Template:Documentation]] 0h49uabfhaeo9mrdbcrfaps8q3fhem8 28004 28003 2019-08-11T20:29:46Z en>Koavf 0 4 revisions imported from [[:wikidata:Template:Doc]] 28003 wikitext text/x-wiki #redirect [[Template:Documentation]] 0h49uabfhaeo9mrdbcrfaps8q3fhem8 28005 28004 2026-10-24T01:09:05Z Kiran Gopi 624 [[:en:Template:Doc]] എന്നതിൽ നിന്ന് 5 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28003 wikitext text/x-wiki #redirect [[Template:Documentation]] 0h49uabfhaeo9mrdbcrfaps8q3fhem8 ഫലകം:Maintenance category/doc 10 7369 28006 2020-05-13T09:35:58Z en>Dibbydib 0 Created page with "== Usage == This template is to be used as <code><nowiki>{{Maintenance category}}</nowiki></code> for maintenance categories on Wikiquote that may possibly be empty at some po..." 28006 wikitext text/x-wiki == Usage == This template is to be used as <code><nowiki>{{Maintenance category}}</nowiki></code> for maintenance categories on Wikiquote that may possibly be empty at some point. If the category this template is placed is normally, or should normally be empty, then the template should be placed like <code><nowiki>{{Maintenance category|empty}}</nowiki></code>. g6mdc8ootdw41bfcwzmf08yekqq528v 28007 28006 2020-05-13T09:36:33Z en>Dibbydib 0 {{Documentation subpage}} 28007 wikitext text/x-wiki {{Documentation subpage}} == Usage == This template is to be used as <code><nowiki>{{Maintenance category}}</nowiki></code> for maintenance categories on Wikiquote that may possibly be empty at some point. If the category this template is placed is normally, or should normally be empty, then the template should be placed like <code><nowiki>{{Maintenance category|empty}}</nowiki></code>. b0v6jj5o0buykok7chssw77e3pi1pbj 28008 28007 2026-10-24T01:09:05Z Kiran Gopi 624 [[:en:Template:Maintenance_category/doc]] എന്നതിൽ നിന്ന് 2 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28007 wikitext text/x-wiki {{Documentation subpage}} == Usage == This template is to be used as <code><nowiki>{{Maintenance category}}</nowiki></code> for maintenance categories on Wikiquote that may possibly be empty at some point. If the category this template is placed is normally, or should normally be empty, then the template should be placed like <code><nowiki>{{Maintenance category|empty}}</nowiki></code>. b0v6jj5o0buykok7chssw77e3pi1pbj ഫലകം:Hlist/styles.css 10 7370 28013 2022-12-26T18:00:17Z w>Izno 0 actually remove that block, someone can dig for authorship 28013 sanitized-css text/css /* {{pp-protected|reason=match parent|small=yes}} */ /* * hlist styles are defined in core and Minerva and differ in Minerva. The * current definitions here (2023-01-01) are sufficient to override Minerva * without use of the hlist-separated class. The most problematic styles were * related to margin, padding, and the bullet. Check files listed at * [[MediaWiki talk:Common.css/to do#hlist-separated]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can maybe be used here to remove the later rule. naive test * seems to work. more testing needed. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } gfbk8cwecy39b1u1zxq4sqqxyf84d2r 28014 28013 2023-06-06T15:30:36Z en>Saroj 0 1 revision imported from [[:w:Template:Hlist/styles.css]] 28013 sanitized-css text/css /* {{pp-protected|reason=match parent|small=yes}} */ /* * hlist styles are defined in core and Minerva and differ in Minerva. The * current definitions here (2023-01-01) are sufficient to override Minerva * without use of the hlist-separated class. The most problematic styles were * related to margin, padding, and the bullet. Check files listed at * [[MediaWiki talk:Common.css/to do#hlist-separated]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can maybe be used here to remove the later rule. naive test * seems to work. more testing needed. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } gfbk8cwecy39b1u1zxq4sqqxyf84d2r 28015 2018-10-30T23:21:28Z w>Jon (WMF) 0 [[WP:AES|←]]Created page with '.mw-parser-output .hlist ul, .mw-parser-output .hlist ol { padding-left: 0; } /* reset hlist margins of Minerva */ .mw-parser-output .hlist li, .mw-parser-outpu...' 28015 sanitized-css text/css .mw-parser-output .hlist ul, .mw-parser-output .hlist ol { padding-left: 0; } /* reset hlist margins of Minerva */ .mw-parser-output .hlist li, .mw-parser-output .hlist dd, .mw-parser-output .hlist dt { margin-right: 0; } .mw-parser-output .hlist li:after, .mw-parser-output .hlist dd:after { content: " · "; font-weight: bold; } .mw-parser-output .hlist dt:after { content: ": "; } /* Should be removed and moved to templates once TemplateStyles is live */ .mw-parser-output .hlist dd:last-child:after, .mw-parser-output .hlist dt:last-child:after, .mw-parser-output .hlist li:last-child:after { content: none; } /* Add parentheses around nested lists */ /* Should be removed and moved to templates once TemplateStyles is live */ .mw-parser-output .hlist dd dd:first-child:before, .mw-parser-output .hlist dd dt:first-child:before, .mw-parser-output .hlist dd li:first-child:before, .mw-parser-output .hlist dt dd:first-child:before, .mw-parser-output .hlist dt dt:first-child:before, .mw-parser-output .hlist dt li:first-child:before, .mw-parser-output .hlist li dd:first-child:before, .mw-parser-output .hlist li dt:first-child:before, .mw-parser-output .hlist li li:first-child:before { content: " ("; font-weight: normal; } /* Should be removed and moved to templates once TemplateStyles is live */ .mw-parser-output .hlist dd dd:last-child:after, .mw-parser-output .hlist dd dt:last-child:after, .mw-parser-output .hlist dd li:last-child:after, .mw-parser-output .hlist dt dd:last-child:after, .mw-parser-output .hlist dt dt:last-child:after, .mw-parser-output .hlist dt li:last-child:after, .mw-parser-output .hlist li dd:last-child:after, .mw-parser-output .hlist li dt:last-child:after, .mw-parser-output .hlist li li:last-child:after { content: ") "; font-weight: normal; } /* Put ordinals in front of ordered list items */ /* Should be removed and moved to templates once TemplateStyles is live */ .mw-parser-output .hlist ol { counter-reset: listitem; } /* Should be removed and moved to templates once TemplateStyles is live */ .mw-parser-output .hlist ol > li { counter-increment: listitem; } /* Should be removed and moved to templates once TemplateStyles is live */ .mw-parser-output .hlist ol > li:before { content: " " counter(listitem) " "; white-space: nowrap; } /* Should be removed and moved to templates once TemplateStyles is live */ .mw-parser-output .hlist dd ol > li:first-child:before, .mw-parser-output .hlist dt ol > li:first-child:before, .mw-parser-output .hlist li ol > li:first-child:before { content: " (" counter(listitem) " "; } guuty5xrc0102na6gdl0u1zelatya16 28016 28015 2021-10-01T00:10:01Z w>IznoPublic 0 conventions 28016 sanitized-css text/css .hlist ul, .hlist ol { padding-left: 0; } /* reset hlist margins of Minerva */ .hlist li, .hlist dd, .hlist dt { margin-right: 0; } .hlist li:after, .hlist dd:after { content: " · "; font-weight: bold; } .hlist dt:after { content: ": "; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ") "; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) " "; white-space: nowrap; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) " "; } aby8cl00s08pas6juz7mwsr2q4pis3c 28017 28016 2021-10-01T00:10:20Z w>IznoPublic 0 and there 28017 sanitized-css text/css .hlist ul, .hlist ol { padding-left: 0; } /* reset hlist margins of Minerva */ .hlist li, .hlist dd, .hlist dt { margin-right: 0; } .hlist li:after, .hlist dd:after { content: " · "; font-weight: bold; } .hlist dt:after { content: ": "; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ") "; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) " "; white-space: nowrap; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) " "; } j4qz8hyxkeod04rog584c8ukgeoxlve 28018 28017 2021-10-01T12:31:26Z w>IznoPublic 0 merge from common.css 28018 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @author [[User:Edokter]] */ /** * Note hlist style usage differs in Minerva and is defined in core as well! * Please check Minerva desktop (and Minerva.css) when changing * See https://phabricator.wikimedia.org/T213239 * TODO: Remove this note when it becomes irrelevant. (Soon?) */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { margin: 0; /* don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again */ display: inline; } /* Display nested lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } .hlist ul, .hlist ol { padding-left: 0; } /* Generate interpuncts */ .hlist dt:after { content: ": "; } .hlist dd:after, .hlist li:after { content: " · "; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) "\a0"; } 6udt44q5zttekjorjlvg6n9a0ownpcs 28019 28018 2021-10-03T22:47:43Z w>Izno 0 adjust note 28019 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @author [[User:Edokter]] */ /** * Note hlist style usage differs in Minerva and is defined in core as well! * Please check Minerva desktop (and Minerva.css) when changing * See https://phabricator.wikimedia.org/T213239 * TODO: Remove this note when it becomes irrelevant. (Soon?) */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display nested lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } .hlist ul, .hlist ol { padding-left: 0; } /* Generate interpuncts */ .hlist dt:after { content: ": "; } .hlist dd:after, .hlist li:after { content: " · "; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) "\a0"; } lxwnnhag4u7t16mpf1qciymgm8tq10v 28020 28019 2021-12-05T15:26:24Z w>IznoPublic 0 two separate things going on here 28020 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @author [[User:Edokter]] */ /** * Note hlist style usage differs in Minerva and is defined in core as well! * Please check Minerva desktop (and Minerva.css) when changing * See https://phabricator.wikimedia.org/T213239 * TODO: Remove this note when it becomes irrelevant. (Soon?) */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } .hlist ul, .hlist ol { padding-left: 0; } /* Generate interpuncts */ .hlist dt:after { content: ": "; } .hlist dd:after, .hlist li:after { content: " · "; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) "\a0"; } ocwcafsd79khraa6z08x325otyti232 28021 28020 2022-01-23T20:22:18Z w>IznoPublic 0 duplicates padding above, ws 28021 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @author [[User:Edokter]] */ /** * Note hlist style usage differs in Minerva and is defined in core as well! * Please check Minerva desktop (and Minerva.css) when changing * See https://phabricator.wikimedia.org/T213239 * TODO: Remove this note when it becomes irrelevant. (Soon?) */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* Generate interpuncts */ .hlist dt:after { content: ": "; } .hlist dd:after, .hlist li:after { content: " · "; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) "\a0"; } msc1h6b8ex93xgg3q5j3avkjwt5yie3 28022 28021 2022-12-25T22:29:36Z w>Izno 0 add TODO for :is() 28022 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @author [[User:Edokter]] */ /** * Note hlist style usage differs in Minerva and is defined in core as well! * Please check Minerva desktop (and Minerva.css) when changing * See https://phabricator.wikimedia.org/T213239 * TODO: Remove this note when it becomes irrelevant. (Soon?) */ /* TODO: When the majority of browsers support it, use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* Generate interpuncts */ .hlist dt:after { content: ": "; } .hlist dd:after, .hlist li:after { content: " · "; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) "\a0"; } qe85k15cyjk2r95yfh01i470mzeyfmv 28023 28022 2022-12-25T22:32:31Z w>Izno 0 adj note 28023 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @author [[User:Edokter]] */ /* * Note hlist style usage differs in Minerva and is defined in core as well! * Please check Minerva desktop (and Minerva.css) when changing * See https://phabricator.wikimedia.org/T213239 * TODO: Remove this note when it becomes irrelevant. (Soon?) */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* Generate interpuncts */ .hlist dt:after { content: ": "; } .hlist dd:after, .hlist li:after { content: " · "; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) "\a0"; } 59a18vk9abv3umfp97nl7o29tmy1ih2 28024 28023 2022-12-25T23:15:32Z w>Izno 0 remove 28024 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @original-author [[User:Edokter]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* Generate interpuncts */ .hlist dt:after { content: ": "; } .hlist dd:after, .hlist li:after { content: " · "; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child:before, .hlist dd dt:first-child:before, .hlist dd li:first-child:before, .hlist dt dd:first-child:before, .hlist dt dt:first-child:before, .hlist dt li:first-child:before, .hlist li dd:first-child:before, .hlist li dt:first-child:before, .hlist li li:first-child:before { content: " ("; font-weight: normal; } .hlist dd dd:last-child:after, .hlist dd dt:last-child:after, .hlist dd li:last-child:after, .hlist dt dd:last-child:after, .hlist dt dt:last-child:after, .hlist dt li:last-child:after, .hlist li dd:last-child:after, .hlist li dt:last-child:after, .hlist li li:last-child:after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li:before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child:before, .hlist dt ol > li:first-child:before, .hlist li ol > li:first-child:before { content: " (" counter(listitem) "\a0"; } 4e1qzyn1ugfog4t9mwldjq2zb9zmooe 28025 28024 2022-12-25T23:25:45Z w>Izno 0 use actual pseudo-element selectors for after and before, all grade C and up support double (correct number) of colons 28025 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @original-author [[User:Edokter]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: believe :not() can be used here to remove the later rule. needs testing. * like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist dd:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } 9hbcv3eya9c0bnuiz69ew23nh5hyf2q 28026 28025 2022-12-25T23:33:03Z w>Izno 0 li 28026 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @original-author [[User:Edokter]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: believe :not() can be used here to remove the later rule. needs testing. * like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } dm9474xmvrvqtoq6axl5lau7c15dn6h 28027 28026 2022-12-25T23:36:32Z w>Izno 0 naive works 28027 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @original-author [[User:Edokter]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can be used here to remove the later rule. mor testing needed * naive test seems to work. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } bkbus7qurn5d0e0uwssqxaoxk3g5u1a 28028 28027 2022-12-25T23:37:25Z w>Izno 0 one final adjustment 28028 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @original-author [[User:Edokter]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can maybe be used here to remove the later rule. naive test * seems to work. more testing needed. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } l5nvxk9l91se1eqzansqp6w83vvsy2c 28029 28028 2022-12-26T00:09:37Z w>Izno 0 Protected "[[Template:Hlist/styles.css]]": match parent ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite)) 28028 sanitized-css text/css /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @original-author [[User:Edokter]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can maybe be used here to remove the later rule. naive test * seems to work. more testing needed. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } l5nvxk9l91se1eqzansqp6w83vvsy2c 28030 28029 2022-12-26T00:09:37Z w>Izno 0 Adding {{pp-protected}} 28030 sanitized-css text/css /* {{pp-protected|reason=match parent|small=yes}} */ /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @original-author [[User:Edokter]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can maybe be used here to remove the later rule. naive test * seems to work. more testing needed. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } et9vcg5w3lotm7typp2dg3ezaq99tgt 28031 28030 2022-12-26T17:54:30Z w>Izno 0 re-add this note on reflection 28031 sanitized-css text/css /* {{pp-protected|reason=match parent|small=yes}} */ /* Style for horizontal lists (separator following item). @source mediawiki.org/wiki/Snippets/Horizontal_lists @revision 8 (2016-05-21) @original-author [[User:Edokter]] */ /* * hlist styles are defined in core and Minerva and differ in Minerva. The * current definitions here (2023-01-01) are sufficient to override Minerva * without use of the hlist-separated class. The most problematic styles were * related to margin, padding, and the bullet. Check files listed at * [[MediaWiki talk:Common.css/to do#hlist-separated]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can maybe be used here to remove the later rule. naive test * seems to work. more testing needed. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } nnbjoiwm6k20icwxjdsoee3icjdvbfm 28032 28014 2025-12-27T04:35:56Z en>Codename Noreste 0 17 revisions imported from [[:w:Template:Hlist/styles.css]]: Importing, required for Sp-contributions-footer. 28013 sanitized-css text/css /* {{pp-protected|reason=match parent|small=yes}} */ /* * hlist styles are defined in core and Minerva and differ in Minerva. The * current definitions here (2023-01-01) are sufficient to override Minerva * without use of the hlist-separated class. The most problematic styles were * related to margin, padding, and the bullet. Check files listed at * [[MediaWiki talk:Common.css/to do#hlist-separated]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can maybe be used here to remove the later rule. naive test * seems to work. more testing needed. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } gfbk8cwecy39b1u1zxq4sqqxyf84d2r 28033 28032 2026-10-24T01:15:47Z Kiran Gopi 624 [[:en:Template:Hlist/styles.css]] എന്നതിൽ നിന്ന് 20 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28013 sanitized-css text/css /* {{pp-protected|reason=match parent|small=yes}} */ /* * hlist styles are defined in core and Minerva and differ in Minerva. The * current definitions here (2023-01-01) are sufficient to override Minerva * without use of the hlist-separated class. The most problematic styles were * related to margin, padding, and the bullet. Check files listed at * [[MediaWiki talk:Common.css/to do#hlist-separated]] */ /* * TODO: When the majority of readership supports it (or some beautiful world * in which grade C support is above the minimum threshold), use :is() */ .hlist dl, .hlist ol, .hlist ul { margin: 0; padding: 0; } /* Display list items inline */ .hlist dd, .hlist dt, .hlist li { /* * don't trust the note that says margin doesn't work with inline * removing margin: 0 makes dds have margins again * We also want to reset margin-right in Minerva */ margin: 0; display: inline; } /* Display requested top-level lists inline */ .hlist.inline, .hlist.inline dl, .hlist.inline ol, .hlist.inline ul, /* Display nested lists inline */ .hlist dl dl, .hlist dl ol, .hlist dl ul, .hlist ol dl, .hlist ol ol, .hlist ol ul, .hlist ul dl, .hlist ul ol, .hlist ul ul { display: inline; } /* Hide empty list items */ .hlist .mw-empty-li { display: none; } /* TODO: :not() can maybe be used here to remove the later rule. naive test * seems to work. more testing needed. like so: *.hlist dt:not(:last-child)::after { * content: ": "; *} *.hlist dd:not(:last-child)::after, *.hlist li:not(:last-child)::after { * content: " · "; * font-weight: bold; *} */ /* Generate interpuncts */ .hlist dt::after { content: ": "; } .hlist dd::after, .hlist li::after { content: " · "; font-weight: bold; } .hlist dd:last-child::after, .hlist dt:last-child::after, .hlist li:last-child::after { content: none; } /* Add parentheses around nested lists */ .hlist dd dd:first-child::before, .hlist dd dt:first-child::before, .hlist dd li:first-child::before, .hlist dt dd:first-child::before, .hlist dt dt:first-child::before, .hlist dt li:first-child::before, .hlist li dd:first-child::before, .hlist li dt:first-child::before, .hlist li li:first-child::before { content: " ("; font-weight: normal; } .hlist dd dd:last-child::after, .hlist dd dt:last-child::after, .hlist dd li:last-child::after, .hlist dt dd:last-child::after, .hlist dt dt:last-child::after, .hlist dt li:last-child::after, .hlist li dd:last-child::after, .hlist li dt:last-child::after, .hlist li li:last-child::after { content: ")"; font-weight: normal; } /* Put ordinals in front of ordered list items */ .hlist ol { counter-reset: listitem; } .hlist ol > li { counter-increment: listitem; } .hlist ol > li::before { content: " " counter(listitem) "\a0"; } .hlist dd ol > li:first-child::before, .hlist dt ol > li:first-child::before, .hlist li ol > li:first-child::before { content: " (" counter(listitem) "\a0"; } gfbk8cwecy39b1u1zxq4sqqxyf84d2r ഫലകം:Pp-protected 10 7371 28034 2024-10-31T22:49:43Z w>Primefac 0 /* top */ avoid double redir 28034 wikitext text/x-wiki #REDIRECT [[Template:Protection padlock]] {{Rcat shell| {{R from move}} {{R from long name}} {{R with history}} }} [[Category:Top icon protection templates]] fggdzzf86ur8bq36yd27gkfxl333uwg 28035 28034 2026-07-12T16:12:24Z en>Codename Noreste 0 1 revision imported from [[:w:Template:Pp-protected]]: Importing a protection padlock template for any page. 28034 wikitext text/x-wiki #REDIRECT [[Template:Protection padlock]] {{Rcat shell| {{R from move}} {{R from long name}} {{R with history}} }} [[Category:Top icon protection templates]] fggdzzf86ur8bq36yd27gkfxl333uwg 28036 28035 2026-10-24T01:15:48Z Kiran Gopi 624 [[:en:Template:Pp-protected]] എന്നതിൽ നിന്ന് 2 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28034 wikitext text/x-wiki #REDIRECT [[Template:Protection padlock]] {{Rcat shell| {{R from move}} {{R from long name}} {{R with history}} }} [[Category:Top icon protection templates]] fggdzzf86ur8bq36yd27gkfxl333uwg ഘടകം:Effective protection expiry 828 7372 28037 2015-12-10T20:08:54Z w>Cenarium 0 new! 28037 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local expiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', pagename) if expiry ~= '' then return expiry else return 'unknown' end end return p rbqdthgf6zjynxk9gjeucrpugzy1ael 28038 28037 2015-12-10T20:14:47Z w>Cenarium 0 28038 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local expiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', pagename) if expiry ~= '' then return expiry else return 'unknown' end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p noknc6n04tffwng5dgettkq2mamm3jw 28039 28038 2015-12-10T20:22:32Z w>Cenarium 0 28039 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local expiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', pagename) return expiry end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p e367m2zsmq3whu6xjx0rhz0c933xqyc 28040 28039 2015-12-10T20:39:18Z w>Cenarium 0 28040 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local expiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) return expiry end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p 2at65thqma4pyd1rrclsjj8haygf186 28041 28040 2015-12-10T21:18:12Z w>Cenarium 0 28041 Scribunto text/plain local subString = require('Module:String').sub local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local expiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) return expiry end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p tljdcaalql3rq03ma1wjss8c70u90rd 28042 28041 2015-12-10T21:24:42Z w>Cenarium 0 28042 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) local year = mw.ustring.sub( rawExpiry, 1, 4 ) local month = mw.ustring.sub( rawExpiry, 5, 6 ) local day = mw.ustring.sub( rawExpiry, 7, 8 ) return year .. '-' .. month .. '-' .. day end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p ay7trzqug771m8uh9ztgif3ur5963mc 28043 28042 2015-12-10T21:28:25Z w>Cenarium 0 28043 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' else local year = mw.ustring.sub( rawExpiry, 1, 4 ) local month = mw.ustring.sub( rawExpiry, 5, 6 ) local day = mw.ustring.sub( rawExpiry, 7, 8 ) return year .. '-' .. month .. '-' .. day end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p s1czxhtt1tc1qo65qvbropd1gnxsjsu 28044 28043 2015-12-11T16:24:21Z w>Cenarium 0 Protected "[[Module:Effective protection expiry]]": [[WP:MOVP|Highly visible page]]: looks ready for deploy in protection banner ([Edit=Allow only template editors and admins] (indefinite) [Move=Allow only template editors and admins] (indefinite)) 28043 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' else local year = mw.ustring.sub( rawExpiry, 1, 4 ) local month = mw.ustring.sub( rawExpiry, 5, 6 ) local day = mw.ustring.sub( rawExpiry, 7, 8 ) return year .. '-' .. month .. '-' .. day end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p s1czxhtt1tc1qo65qvbropd1gnxsjsu 28045 28044 2015-12-13T20:15:13Z w>Cenarium 0 handles special pages 28045 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year = mw.ustring.sub( rawExpiry, 1, 4 ) local month = mw.ustring.sub( rawExpiry, 5, 6 ) local day = mw.ustring.sub( rawExpiry, 7, 8 ) return year .. '-' .. month .. '-' .. day end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p rv7wgtq41hom9jbry0t1k9873xy5fi6 28046 28045 2016-07-16T02:37:59Z w>Mr. Stradivarius 0 return a yyyy-mm-ddThh:mm:ss timestamp, rather than just yyyy-mm-dd 28046 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year, month, day, hour, minute, second = rawExpiry:match( '^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$' ) if year then return string.format( '%s-%s-%sT%s:%s:%s', year, month, day, hour, minute, second ) else error('internal error in Module:Effective protection expiry; malformed expiry timestamp') end end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p p3ybbtrk205qj5h07g1yt56g8jqpfuw 28047 28046 2016-09-23T10:40:06Z w>Cenarium 0 using mw.ext.FlaggedRevs.getStabilitySettings(title) to get expiry for FlaggedRevs 28047 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then return mw.ext.FlaggedRevs.getStabilitySettings(title).expiry elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year, month, day, hour, minute, second = rawExpiry:match( '^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$' ) if year then return string.format( '%s-%s-%sT%s:%s:%s', year, month, day, hour, minute, second ) else error('internal error in Module:Effective protection expiry; malformed expiry timestamp') end end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p rwx71h8de2lcz0hhpmkkjfn2lt6awzi 28048 28047 2016-10-13T22:30:40Z w>Jackmcbarn 0 don't error if the page isn't under PC 28048 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local stabilitySettings = mw.ext.FlaggedRevs.getStabilitySettings(title) return stabilitySettings and stabilitySettings.expiry or 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year, month, day, hour, minute, second = rawExpiry:match( '^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$' ) if year then return string.format( '%s-%s-%sT%s:%s:%s', year, month, day, hour, minute, second ) else error('internal error in Module:Effective protection expiry; malformed expiry timestamp') end end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p i1wms02y1w048cq6uttka18a5pjzp63 28049 28048 2017-06-23T21:54:29Z w>MarcoAurelio 0 Protected "[[Module:Effective protection expiry]]": High-risk Lua module ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)) 28048 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local stabilitySettings = mw.ext.FlaggedRevs.getStabilitySettings(title) return stabilitySettings and stabilitySettings.expiry or 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year, month, day, hour, minute, second = rawExpiry:match( '^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$' ) if year then return string.format( '%s-%s-%sT%s:%s:%s', year, month, day, hour, minute, second ) else error('internal error in Module:Effective protection expiry; malformed expiry timestamp') end end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p i1wms02y1w048cq6uttka18a5pjzp63 28050 28049 2020-04-01T06:12:42Z w>MusikAnimal 0 1 revision imported 28048 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local stabilitySettings = mw.ext.FlaggedRevs.getStabilitySettings(title) return stabilitySettings and stabilitySettings.expiry or 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year, month, day, hour, minute, second = rawExpiry:match( '^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$' ) if year then return string.format( '%s-%s-%sT%s:%s:%s', year, month, day, hour, minute, second ) else error('internal error in Module:Effective protection expiry; malformed expiry timestamp') end end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p i1wms02y1w048cq6uttka18a5pjzp63 28051 28050 2022-02-23T10:59:29Z w>Xaosflux 0 Changed protection settings for "[[Module:Effective protection expiry]]": used in the mediawiki interface / match [[Module:Effective protection level]] ([Edit=Require administrator access] (indefinite) [Move=Require administrator access] (indefinite)) 28048 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local stabilitySettings = mw.ext.FlaggedRevs.getStabilitySettings(title) return stabilitySettings and stabilitySettings.expiry or 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year, month, day, hour, minute, second = rawExpiry:match( '^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$' ) if year then return string.format( '%s-%s-%sT%s:%s:%s', year, month, day, hour, minute, second ) else error('internal error in Module:Effective protection expiry; malformed expiry timestamp') end end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p i1wms02y1w048cq6uttka18a5pjzp63 28052 28051 2025-12-30T02:33:29Z en>Codename Noreste 0 15 revisions imported from [[:w:Module:Effective_protection_expiry]]: Required for [[Module:Protection banner]]. 28048 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local stabilitySettings = mw.ext.FlaggedRevs.getStabilitySettings(title) return stabilitySettings and stabilitySettings.expiry or 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year, month, day, hour, minute, second = rawExpiry:match( '^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$' ) if year then return string.format( '%s-%s-%sT%s:%s:%s', year, month, day, hour, minute, second ) else error('internal error in Module:Effective protection expiry; malformed expiry timestamp') end end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p i1wms02y1w048cq6uttka18a5pjzp63 28053 28052 2026-10-24T01:15:48Z Kiran Gopi 624 [[:en:Module:Effective_protection_expiry]] എന്നതിൽ നിന്ന് 16 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28048 Scribunto text/plain local p = {} -- Returns the expiry of a restriction of an action on a given title, or unknown if it cannot be known. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local stabilitySettings = mw.ext.FlaggedRevs.getStabilitySettings(title) return stabilitySettings and stabilitySettings.expiry or 'unknown' elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' then error( 'First parameter must be one of edit, move, create, upload, autoreview', 2 ) end local rawExpiry = mw.getCurrentFrame():callParserFunction('PROTECTIONEXPIRY', action, pagename) if rawExpiry == 'infinity' then return 'infinity' elseif rawExpiry == '' then return 'unknown' else local year, month, day, hour, minute, second = rawExpiry:match( '^(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)$' ) if year then return string.format( '%s-%s-%sT%s:%s:%s', year, month, day, hour, minute, second ) else error('internal error in Module:Effective protection expiry; malformed expiry timestamp') end end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p i1wms02y1w048cq6uttka18a5pjzp63 ഘടകം:Effective protection level 828 7373 28054 2024-08-25T19:57:28Z 2604:3D08:9476:BE00:54CE:32F2:7EBC:42BF Created page with "local p = {} -- Returns the permission required to perform a given action on a given title. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local leve..." 28054 Scribunto text/plain local p = {} -- Returns the permission required to perform a given action on a given title. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local level = mw.ext.FlaggedRevs.getStabilitySettings(title) level = level and level.autoreview if level == 'review' then return 'reviewer' elseif level ~= '' then return level else return nil -- not '*'. a page not being PC-protected is distinct from it being PC-protected with anyone able to review. also not '', as that would mean PC-protected but nobody can review end elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' and action ~= 'undelete' then error( 'First parameter must be one of edit, move, create, upload, undelete, autoreview', 2 ) end if title.namespace == 8 then -- MediaWiki namespace if title.text:sub(-3) == '.js' or title.text:sub(-4) == '.css' or title.contentModel == 'javascript' or title.contentModel == 'css' then -- site JS or CSS page return 'interfaceadmin' else -- any non-JS/CSS MediaWiki page return 'sysop' end elseif title.namespace == 2 and title.isSubpage then if title.contentModel == 'javascript' or title.contentModel == 'css' then -- user JS or CSS page return 'interfaceadmin' elseif title.contentModel == 'json' then -- user JSON page return 'sysop' end end if action == 'undelete' then return 'sysop' end local level = title.protectionLevels[action] and title.protectionLevels[action][1] if level == 'sysop' or level == 'editprotected' then return 'sysop' elseif title.cascadingProtection.restrictions[action] and title.cascadingProtection.restrictions[action][1] then -- used by a cascading-protected page return 'sysop' elseif level == 'templateeditor' then return 'templateeditor' elseif action == 'move' then local blacklistentry = mw.ext.TitleBlacklist.test('edit', pagename) -- Testing action edit is correct, since this is for the source page. The target page name gets tested with action move. if blacklistentry and not blacklistentry.params.autoconfirmed then return 'templateeditor' elseif title.namespace == 6 then return 'filemover' elseif level == 'extendedconfirmed' then return 'extendedconfirmed' else return 'autoconfirmed' end end local blacklistentry = mw.ext.TitleBlacklist.test(action, pagename) if blacklistentry then if not blacklistentry.params.autoconfirmed then return 'templateeditor' elseif level == 'extendedconfirmed' then return 'extendedconfirmed' else return 'autoconfirmed' end elseif level == 'editsemiprotected' then -- create-semiprotected pages return this for some reason return 'autoconfirmed' elseif level then return level elseif action == 'upload' then return 'autoconfirmed' elseif action == 'create' and title.namespace % 2 == 0 and title.namespace ~= 118 then -- You need to be registered, but not autoconfirmed, to create non-talk pages other than drafts if title.namespace == 0 then return 'autoconfirmed' -- Per Wikipedia’s [[WP:ACPERM]], you need to be autoconfirmed to create pages in mainspace end return 'user' else return '*' end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p qm94j4opv51mdkhbilou98mqlh5u985 28055 28054 2026-01-22T20:13:14Z en>Codename Noreste 0 Replacing extendedconfirmed with autopatrol. 28055 Scribunto text/plain local p = {} -- Returns the permission required to perform a given action on a given title. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local level = mw.ext.FlaggedRevs.getStabilitySettings(title) level = level and level.autoreview if level == 'review' then return 'reviewer' elseif level ~= '' then return level else return nil -- not '*'. a page not being PC-protected is distinct from it being PC-protected with anyone able to review. also not '', as that would mean PC-protected but nobody can review end elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' and action ~= 'undelete' then error( 'First parameter must be one of edit, move, create, upload, undelete, autoreview', 2 ) end if title.namespace == 8 then -- MediaWiki namespace if title.text:sub(-3) == '.js' or title.text:sub(-4) == '.css' or title.contentModel == 'javascript' or title.contentModel == 'css' then -- site JS or CSS page return 'interfaceadmin' else -- any non-JS/CSS MediaWiki page return 'sysop' end elseif title.namespace == 2 and title.isSubpage then if title.contentModel == 'javascript' or title.contentModel == 'css' then -- user JS or CSS page return 'interfaceadmin' elseif title.contentModel == 'json' then -- user JSON page return 'sysop' end end if action == 'undelete' then return 'sysop' end local level = title.protectionLevels[action] and title.protectionLevels[action][1] if level == 'sysop' or level == 'editprotected' then return 'sysop' elseif title.cascadingProtection.restrictions[action] and title.cascadingProtection.restrictions[action][1] then -- used by a cascading-protected page return 'sysop' elseif level == 'templateeditor' then return 'templateeditor' elseif action == 'move' then local blacklistentry = mw.ext.TitleBlacklist.test('edit', pagename) -- Testing action edit is correct, since this is for the source page. The target page name gets tested with action move. if blacklistentry and not blacklistentry.params.autoconfirmed then return 'templateeditor' elseif title.namespace == 6 then return 'filemover' elseif level == 'autopatrol' then return 'autopatrol' else return 'autoconfirmed' end end local blacklistentry = mw.ext.TitleBlacklist.test(action, pagename) if blacklistentry then if not blacklistentry.params.autoconfirmed then return 'templateeditor' elseif level == 'autopatrol' then return 'autopatrol' else return 'autoconfirmed' end elseif level == 'editsemiprotected' then -- create-semiprotected pages return this for some reason return 'autoconfirmed' elseif level then return level elseif action == 'upload' then return 'autoconfirmed' elseif action == 'create' and title.namespace % 2 == 0 and title.namespace ~= 118 then -- You need to be registered, but not autoconfirmed, to create non-talk pages other than drafts if title.namespace == 0 then return 'autoconfirmed' -- Per Wikipedia’s [[WP:ACPERM]], you need to be autoconfirmed to create pages in mainspace end return 'user' else return '*' end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p 4qf0a7zy7ztbc5sgf4fhf0j8kph1gf3 28056 28055 2026-01-23T15:48:20Z en>Codename Noreste 0 Adding to account for editautopatrolprotected. 28056 Scribunto text/plain local p = {} -- Returns the permission required to perform a given action on a given title. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local level = mw.ext.FlaggedRevs.getStabilitySettings(title) level = level and level.autoreview if level == 'review' then return 'reviewer' elseif level ~= '' then return level else return nil -- not '*'. a page not being PC-protected is distinct from it being PC-protected with anyone able to review. also not '', as that would mean PC-protected but nobody can review end elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' and action ~= 'undelete' then error( 'First parameter must be one of edit, move, create, upload, undelete, autoreview', 2 ) end if title.namespace == 8 then -- MediaWiki namespace if title.text:sub(-3) == '.js' or title.text:sub(-4) == '.css' or title.contentModel == 'javascript' or title.contentModel == 'css' then -- site JS or CSS page return 'interfaceadmin' else -- any non-JS/CSS MediaWiki page return 'sysop' end elseif title.namespace == 2 and title.isSubpage then if title.contentModel == 'javascript' or title.contentModel == 'css' then -- user JS or CSS page return 'interfaceadmin' elseif title.contentModel == 'json' then -- user JSON page return 'sysop' end end if action == 'undelete' then return 'sysop' end local level = title.protectionLevels[action] and title.protectionLevels[action][1] if level == 'sysop' or level == 'editprotected' then return 'sysop' elseif title.cascadingProtection.restrictions[action] and title.cascadingProtection.restrictions[action][1] then -- used by a cascading-protected page return 'sysop' elseif level == 'autopatrol' then return 'autopatrol' elseif action == 'move' then local blacklistentry = mw.ext.TitleBlacklist.test('edit', pagename) -- Testing action edit is correct, since this is for the source page. The target page name gets tested with action move. if blacklistentry and not blacklistentry.params.autoconfirmed then return 'autopatrol' else return 'autoconfirmed' end end local blacklistentry = mw.ext.TitleBlacklist.test(action, pagename) if blacklistentry then if not blacklistentry.params.autoconfirmed then return 'autopatrol' else return 'autoconfirmed' end elseif level == 'editautopatrolprotected' then return 'autopatrol' elseif level == 'editsemiprotected' then -- create-semiprotected pages return this for some reason return 'autoconfirmed' elseif level then return level elseif action == 'upload' then return 'autoconfirmed' elseif action == 'create' and title.namespace % 2 == 0 and title.namespace ~= 118 then -- You need to be registered, but not autoconfirmed, to create non-talk pages other than drafts if title.namespace == 0 then return 'autoconfirmed' -- Per Wikipedia’s [[WP:ACPERM]], you need to be autoconfirmed to create pages in mainspace end return 'user' else return '*' end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p jm3f6tqkt1l4oq6q65330a88ht5mrqm 28057 28056 2026-01-23T16:00:53Z en>Codename Noreste 0 The title blacklist only affects admins and non-autoconfirmed users. 28057 Scribunto text/plain local p = {} -- Returns the permission required to perform a given action on a given title. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local level = mw.ext.FlaggedRevs.getStabilitySettings(title) level = level and level.autoreview if level == 'review' then return 'reviewer' elseif level ~= '' then return level else return nil -- not '*'. a page not being PC-protected is distinct from it being PC-protected with anyone able to review. also not '', as that would mean PC-protected but nobody can review end elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' and action ~= 'undelete' then error( 'First parameter must be one of edit, move, create, upload, undelete, autoreview', 2 ) end if title.namespace == 8 then -- MediaWiki namespace if title.text:sub(-3) == '.js' or title.text:sub(-4) == '.css' or title.contentModel == 'javascript' or title.contentModel == 'css' then -- site JS or CSS page return 'interfaceadmin' else -- any non-JS/CSS MediaWiki page return 'sysop' end elseif title.namespace == 2 and title.isSubpage then if title.contentModel == 'javascript' or title.contentModel == 'css' then -- user JS or CSS page return 'interfaceadmin' elseif title.contentModel == 'json' then -- user JSON page return 'sysop' end end if action == 'undelete' then return 'sysop' end local level = title.protectionLevels[action] and title.protectionLevels[action][1] if level == 'sysop' or level == 'editprotected' then return 'sysop' elseif title.cascadingProtection.restrictions[action] and title.cascadingProtection.restrictions[action][1] then -- used by a cascading-protected page return 'sysop' elseif action == 'move' then local blacklistentry = mw.ext.TitleBlacklist.test('edit', pagename) -- Testing action edit is correct, since this is for the source page. The target page name gets tested with action move. if blacklistentry and not blacklistentry.params.autoconfirmed then return 'autoconfirmed' end end local blacklistentry = mw.ext.TitleBlacklist.test(action, pagename) if blacklistentry then if not blacklistentry.params.autoconfirmed then return 'autoconfirmed' end elseif level == 'editautopatrolprotected' then return 'autopatrol' elseif level == 'editsemiprotected' then -- create-semiprotected pages return this for some reason return 'autoconfirmed' elseif level then return level elseif action == 'upload' then return 'autoconfirmed' elseif action == 'create' and title.namespace % 2 == 0 and title.namespace ~= 118 then -- You need to be registered, but not autoconfirmed, to create non-talk pages other than drafts if title.namespace == 0 then return 'autoconfirmed' -- Per Wikipedia’s [[WP:ACPERM]], you need to be autoconfirmed to create pages in mainspace end return 'user' else return '*' end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p 31wjp5wsevv1wox8hqujys2f1pg02hf 28058 28057 2026-10-24T01:15:49Z Kiran Gopi 624 [[:en:Module:Effective_protection_level]] എന്നതിൽ നിന്ന് 4 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28057 Scribunto text/plain local p = {} -- Returns the permission required to perform a given action on a given title. -- If no title is specified, the title of the page being displayed is used. function p._main(action, pagename) local title if type(pagename) == 'table' and pagename.prefixedText then title = pagename elseif pagename then title = mw.title.new(pagename) else title = mw.title.getCurrentTitle() end pagename = title.prefixedText if action == 'autoreview' then local level = mw.ext.FlaggedRevs.getStabilitySettings(title) level = level and level.autoreview if level == 'review' then return 'reviewer' elseif level ~= '' then return level else return nil -- not '*'. a page not being PC-protected is distinct from it being PC-protected with anyone able to review. also not '', as that would mean PC-protected but nobody can review end elseif action ~= 'edit' and action ~= 'move' and action ~= 'create' and action ~= 'upload' and action ~= 'undelete' then error( 'First parameter must be one of edit, move, create, upload, undelete, autoreview', 2 ) end if title.namespace == 8 then -- MediaWiki namespace if title.text:sub(-3) == '.js' or title.text:sub(-4) == '.css' or title.contentModel == 'javascript' or title.contentModel == 'css' then -- site JS or CSS page return 'interfaceadmin' else -- any non-JS/CSS MediaWiki page return 'sysop' end elseif title.namespace == 2 and title.isSubpage then if title.contentModel == 'javascript' or title.contentModel == 'css' then -- user JS or CSS page return 'interfaceadmin' elseif title.contentModel == 'json' then -- user JSON page return 'sysop' end end if action == 'undelete' then return 'sysop' end local level = title.protectionLevels[action] and title.protectionLevels[action][1] if level == 'sysop' or level == 'editprotected' then return 'sysop' elseif title.cascadingProtection.restrictions[action] and title.cascadingProtection.restrictions[action][1] then -- used by a cascading-protected page return 'sysop' elseif action == 'move' then local blacklistentry = mw.ext.TitleBlacklist.test('edit', pagename) -- Testing action edit is correct, since this is for the source page. The target page name gets tested with action move. if blacklistentry and not blacklistentry.params.autoconfirmed then return 'autoconfirmed' end end local blacklistentry = mw.ext.TitleBlacklist.test(action, pagename) if blacklistentry then if not blacklistentry.params.autoconfirmed then return 'autoconfirmed' end elseif level == 'editautopatrolprotected' then return 'autopatrol' elseif level == 'editsemiprotected' then -- create-semiprotected pages return this for some reason return 'autoconfirmed' elseif level then return level elseif action == 'upload' then return 'autoconfirmed' elseif action == 'create' and title.namespace % 2 == 0 and title.namespace ~= 118 then -- You need to be registered, but not autoconfirmed, to create non-talk pages other than drafts if title.namespace == 0 then return 'autoconfirmed' -- Per Wikipedia’s [[WP:ACPERM]], you need to be autoconfirmed to create pages in mainspace end return 'user' else return '*' end end setmetatable(p, { __index = function(t, k) return function(frame) return t._main(k, frame.args[1]) end end }) return p 31wjp5wsevv1wox8hqujys2f1pg02hf ഘടകം:Protection banner 828 7374 28059 2014-02-25T02:58:48Z w>Mr. Stradivarius 0 make a start on the data structure 28059 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = {} -- The naming scheme is: protection type - protection level - namespace - reason categories['edit-semi-user-all'] = 'Wikipedia semi-protected user and user talk pages' categories['edit-semi-project-all'] = 'Semi-protected project pages' categories['edit-semi-file-all'] = 'Semi-protected images' categories['edit-semi-template-all'] = 'Wikipedia semi-protected templates' categories['edit-semi-portal-all'] = 'Semi-protected portals' categories['edit-semi-talk-all'] = 'Semi-protected talk pages' categories['edit-semi-other-vandalism'] 'Wikipedia pages semi-protected against vandalism' categories['edit-full-user-all'] = 'Wikipedia protected user and user talk pages' categories['edit-full-file-all'] = 'Protected images' categories['edit-full-project-all'] = 'Protected project pages' categories['edit-full-template-all'] = 'Wikipedia protected templates' categories['edit-full-talk-all'] = 'Protected talk pages' categories['edit-full-all-vandalism'] = 'Wikipedia pages protected against vandalism' local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } 7zpnr8lv9q748fdbbxxshzfn8hq5sl1 28060 28059 2014-02-25T09:53:52Z w>Mr. Stradivarius 0 fix missing equals 28060 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = {} -- The naming scheme is: protection type - protection level - namespace - reason categories['edit-semi-user-all'] = 'Wikipedia semi-protected user and user talk pages' categories['edit-semi-project-all'] = 'Semi-protected project pages' categories['edit-semi-file-all'] = 'Semi-protected images' categories['edit-semi-template-all'] = 'Wikipedia semi-protected templates' categories['edit-semi-portal-all'] = 'Semi-protected portals' categories['edit-semi-talk-all'] = 'Semi-protected talk pages' categories['edit-semi-other-vandalism'] = 'Wikipedia pages semi-protected against vandalism' categories['edit-full-user-all'] = 'Wikipedia protected user and user talk pages' categories['edit-full-file-all'] = 'Protected images' categories['edit-full-project-all'] = 'Protected project pages' categories['edit-full-template-all'] = 'Wikipedia protected templates' categories['edit-full-talk-all'] = 'Protected talk pages' categories['edit-full-all-vandalism'] = 'Wikipedia pages protected against vandalism' local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } 29gtokleixzoqjzho3xs2wb2qvgn9ql 28061 28060 2014-02-25T11:00:06Z w>Mr. Stradivarius 0 add some more categories 28061 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = {} -- The naming scheme is: protection type - protection level - namespace - reason categories['edit-semi-user-all'] = 'Wikipedia semi-protected user and user talk pages' categories['edit-semi-project-all'] = 'Semi-protected project pages' categories['edit-semi-file-all'] = 'Semi-protected images' categories['edit-semi-template-all'] = 'Wikipedia semi-protected templates' categories['edit-semi-portal-all'] = 'Semi-protected portals' categories['edit-semi-talk-all'] = 'Semi-protected talk pages' categories['edit-semi-other-vandalism'] = 'Wikipedia pages semi-protected against vandalism' categories['edit-full-user-all'] = 'Wikipedia protected user and user talk pages' categories['edit-full-file-all'] = 'Protected images' categories['edit-full-project-all'] = 'Protected project pages' categories['edit-full-template-all'] = 'Wikipedia protected templates' categories['edit-full-talk-all'] = 'Protected talk pages' categories['edit-full-all-vandalism'] = 'Wikipedia pages protected against vandalism' categories['edit-semi-all-dispute'] = 'Wikipedia pages semi-protected due to dispute' categories['edit-full-all-dispute'] = 'Wikipedia pages protected due to dispute' categories['move-full-all-dispute'] = 'Wikipedia pages move-protected due to dispute' categories['move-full-user-all'] = 'Wikipedia move-protected user and user talk pages' categories['move-full-project-all'] = 'Wikipedia move-protected project pages' categories['move-full-portal-all'] = 'Wikipedia move-protected portals' local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } nq7qvsd5hyenrqw3mf149qu4d2rbd22 28062 28061 2014-03-02T12:00:16Z w>Mr. Stradivarius 0 change category table scheme 28062 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { { name = 'Wikipedia semi-protected user and user talk pages', type = 'edit', level = 'semi', ns = {[2] = true, [3] = true}, -- User and user talk reason - 'all' }, { name = 'Semi-protected project pages', type = 'edit', level = 'semi', ns = {[4] = true}, -- Project reason = 'all' }, { name = 'Semi-protected images', type = 'edit', level = 'semi', ns = {[6] = true}, -- File reason = 'all' }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'semi', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Semi-protected portals', type = 'edit', level = 'semi', ns = {[100] = true}, -- Portal reason = 'all' }, { name = 'Semi-protected talk pages', type = 'edit', level = 'semi', ns = 'talk', reason = 'all' }, { name = 'Wikipedia pages semi-protected against vandalism', type = 'edit', level = 'semi', ns = 'all', reason = 'vandalism' }, { name = 'Wikipedia protected user and user talk pages', type = 'edit', level = 'full', ns = {[2] = true, [3] = true}, -- User and user talk reason = 'all' }, { name = 'Protected images', type = 'edit', level = 'full', ns = 'file', reason = 'all' }, { name = 'Protected project pages', type = 'edit', level = 'full', ns = {[6] = true}, -- File reason = 'all' }, { name = 'Wikipedia protected templates', type = 'edit', level = 'full', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Protected talk pages', type = 'edit', level = 'full', ns = 'talk', reason = 'all' }, { name = 'Wikipedia pages protected against vandalism', type = 'edit', level = 'full', ns = 'all', reason = 'vandalism' }, { name = 'Wikipedia pages semi-protected due to dispute', type = 'edit', level = 'semi', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia pages protected due to dispute', type = 'edit', level = 'full', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia pages move-protected due to dispute', type = 'move', level = 'full', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia move-protected user and user talk pages', type = 'move', level = 'full', ns = {[2] = true, [3] = true}, -- User and user talk reason = 'all' }, { name = 'Wikipedia move-protected project pages', type = 'move', level = 'full', ns = {[4] = true}, -- Project reason = 'all' }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'full', ns = {[100] = true}, -- Portal reason = 'all' }, } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } dme6x90rt6ycs9cffqyjnolqbbps8bk 28063 28062 2014-03-02T12:39:20Z w>Mr. Stradivarius 0 add a (very) preliminary sketch of what the main function might look like 28063 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { { name = 'Wikipedia semi-protected user and user talk pages', type = 'edit', level = 'semi', ns = {[2] = true, [3] = true}, -- User and user talk reason - 'all' }, { name = 'Semi-protected project pages', type = 'edit', level = 'semi', ns = {[4] = true}, -- Project reason = 'all' }, { name = 'Semi-protected images', type = 'edit', level = 'semi', ns = {[6] = true}, -- File reason = 'all' }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'semi', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Semi-protected portals', type = 'edit', level = 'semi', ns = {[100] = true}, -- Portal reason = 'all' }, { name = 'Semi-protected talk pages', type = 'edit', level = 'semi', ns = 'talk', reason = 'all' }, { name = 'Wikipedia pages semi-protected against vandalism', type = 'edit', level = 'semi', ns = 'all', reason = 'vandalism' }, { name = 'Wikipedia protected user and user talk pages', type = 'edit', level = 'full', ns = {[2] = true, [3] = true}, -- User and user talk reason = 'all' }, { name = 'Protected images', type = 'edit', level = 'full', ns = 'file', reason = 'all' }, { name = 'Protected project pages', type = 'edit', level = 'full', ns = {[6] = true}, -- File reason = 'all' }, { name = 'Wikipedia protected templates', type = 'edit', level = 'full', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Protected talk pages', type = 'edit', level = 'full', ns = 'talk', reason = 'all' }, { name = 'Wikipedia pages protected against vandalism', type = 'edit', level = 'full', ns = 'all', reason = 'vandalism' }, { name = 'Wikipedia pages semi-protected due to dispute', type = 'edit', level = 'semi', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia pages protected due to dispute', type = 'edit', level = 'full', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia pages move-protected due to dispute', type = 'move', level = 'full', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia move-protected user and user talk pages', type = 'move', level = 'full', ns = {[2] = true, [3] = true}, -- User and user talk reason = 'all' }, { name = 'Wikipedia move-protected project pages', type = 'move', level = 'full', ns = {[4] = true}, -- Project reason = 'all' }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'full', ns = {[100] = true}, -- Portal reason = 'all' }, } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end return p ncyszrl0v3sqan4nxi1z1a9nd7hgoxk 28064 28063 2014-03-03T11:44:56Z w>Mr. Stradivarius 0 add some more categories 28064 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { { name = 'Wikipedia semi-protected user and user talk pages', type = 'edit', level = 'semi', ns = {[2] = true, [3] = true}, -- User and user talk reason - 'all' }, { name = 'Semi-protected project pages', type = 'edit', level = 'semi', ns = {[4] = true}, -- Project reason = 'all' }, { name = 'Semi-protected images', type = 'edit', level = 'semi', ns = {[6] = true}, -- File reason = 'all' }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'semi', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Semi-protected portals', type = 'edit', level = 'semi', ns = {[100] = true}, -- Portal reason = 'all' }, { name = 'Semi-protected talk pages', type = 'edit', level = 'semi', ns = 'talk', reason = 'all' }, { name = 'Wikipedia pages semi-protected against vandalism', type = 'edit', level = 'semi', ns = 'all', reason = 'vandalism' }, { name = 'Wikipedia protected user and user talk pages', type = 'edit', level = 'full', ns = {[2] = true, [3] = true}, -- User and user talk reason = 'all' }, { name = 'Protected images', type = 'edit', level = 'full', ns = 'file', reason = 'all' }, { name = 'Protected project pages', type = 'edit', level = 'full', ns = {[6] = true}, -- File reason = 'all' }, { name = 'Wikipedia protected templates', type = 'edit', level = 'full', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Protected talk pages', type = 'edit', level = 'full', ns = 'talk', reason = 'all' }, { name = 'Wikipedia pages protected against vandalism', type = 'edit', level = 'full', ns = 'all', reason = 'vandalism' }, { name = 'Wikipedia pages semi-protected due to dispute', type = 'edit', level = 'semi', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia pages protected due to dispute', type = 'edit', level = 'full', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia pages move-protected due to dispute', type = 'move', level = 'full', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia move-protected user and user talk pages', type = 'move', level = 'full', ns = {[2] = true, [3] = true}, -- User and user talk reason = 'all' }, { name = 'Wikipedia move-protected project pages', type = 'move', level = 'full', ns = {[4] = true}, -- Project reason = 'all' }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'full', ns = {[100] = true}, -- Portal reason = 'all' }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'semi', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Wikipedia move-protected templates', type = 'move', level = 'full', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Wikipedia protected templates', type = 'edit', level = 'full', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'full', ns = {[100] = true}, -- Portal reason = 'all' }, { name = 'Wikipedia pages semi-protected from banned users', type = 'edit', level = 'semi', ns = 'all', reason = 'sock' }, { name = 'Wikipedia pages protected from banned users', type = 'edit', level = 'full', ns = 'all', reason = 'sock' }, } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end return p mivxluib7ot1igk16y8btalv2jek30a 28065 28064 2014-03-03T11:51:56Z w>Mr. Stradivarius 0 add blp cats 28065 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { { name = 'Wikipedia semi-protected user and user talk pages', type = 'edit', level = 'semi', ns = {[2] = true, [3] = true}, -- User and user talk reason - 'all' }, { name = 'Semi-protected project pages', type = 'edit', level = 'semi', ns = {[4] = true}, -- Project reason = 'all' }, { name = 'Semi-protected images', type = 'edit', level = 'semi', ns = {[6] = true}, -- File reason = 'all' }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'semi', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Semi-protected portals', type = 'edit', level = 'semi', ns = {[100] = true}, -- Portal reason = 'all' }, { name = 'Semi-protected talk pages', type = 'edit', level = 'semi', ns = 'talk', reason = 'all' }, { name = 'Wikipedia pages semi-protected against vandalism', type = 'edit', level = 'semi', ns = 'all', reason = 'vandalism' }, { name = 'Wikipedia protected user and user talk pages', type = 'edit', level = 'full', ns = {[2] = true, [3] = true}, -- User and user talk reason = 'all' }, { name = 'Protected images', type = 'edit', level = 'full', ns = 'file', reason = 'all' }, { name = 'Protected project pages', type = 'edit', level = 'full', ns = {[6] = true}, -- File reason = 'all' }, { name = 'Wikipedia protected templates', type = 'edit', level = 'full', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Protected talk pages', type = 'edit', level = 'full', ns = 'talk', reason = 'all' }, { name = 'Wikipedia pages protected against vandalism', type = 'edit', level = 'full', ns = 'all', reason = 'vandalism' }, { name = 'Wikipedia pages semi-protected due to dispute', type = 'edit', level = 'semi', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia pages protected due to dispute', type = 'edit', level = 'full', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia pages move-protected due to dispute', type = 'move', level = 'full', ns = 'all', reason = 'dispute' }, { name = 'Wikipedia move-protected user and user talk pages', type = 'move', level = 'full', ns = {[2] = true, [3] = true}, -- User and user talk reason = 'all' }, { name = 'Wikipedia move-protected project pages', type = 'move', level = 'full', ns = {[4] = true}, -- Project reason = 'all' }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'full', ns = {[100] = true}, -- Portal reason = 'all' }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'semi', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Wikipedia move-protected templates', type = 'move', level = 'full', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Wikipedia protected templates', type = 'edit', level = 'full', ns = {[10] = true}, -- Template reason = 'all' }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'full', ns = {[100] = true}, -- Portal reason = 'all' }, { name = 'Wikipedia pages semi-protected from banned users', type = 'edit', level = 'semi', ns = 'all', reason = 'sock' }, { name = 'Wikipedia pages protected from banned users', type = 'edit', level = 'full', ns = 'all', reason = 'sock' }, { name = 'Wikipedia temporarily semi-protected biographies of living people', type = 'edit', level = 'semi', ns = 'all', reason = 'blp', expiry = 'temp' }, { name = 'Wikipedia temporarily protected biographies of living people', type = 'edit', level = 'full', ns = 'all', reason = 'blp', expiry = 'temp' }, { name = 'Wikipedia indefinitely semi-protected biographies of living people', type = 'edit', level = 'semi', ns = 'all', reason = 'blp', expiry = 'indef' }, { name = 'Wikipedia indefinitely protected biographies of living people', type = 'edit', level = 'full', ns = 'all', reason = 'blp', expiry = 'indef' }, } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end return p l8u5oaaj2r3n5e3ypvphx9dgrjb4wt2 28066 28065 2014-03-03T14:00:10Z w>Mr. Stradivarius 0 finish list of categories 28066 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { { name = 'Wikipedia semi-protected user and user talk pages', type = 'edit', level = 'autoconfirmed', ns = {[2] = true, [3] = true} -- User and user talk }, { name = 'Semi-protected project pages', type = 'edit', level = 'autoconfirmed', ns = {[4] = true} -- Project }, { name = 'Semi-protected images', type = 'edit', level = 'autoconfirmed', ns = {[6] = true} -- File }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'autoconfirmed', ns = {[10] = true} -- Template }, { name = 'Semi-protected portals', type = 'edit', level = 'autoconfirmed', ns = {[100] = true} -- Portal }, { name = 'Semi-protected talk pages', type = 'edit', level = 'autoconfirmed', ns = {talk = true} }, { name = 'Wikipedia pages semi-protected against vandalism', type = 'edit', level = 'autoconfirmed', reason = 'vandalism' }, { name = 'Wikipedia protected user and user talk pages', type = 'edit', level = 'sysop', ns = {[2] = true, [3] = true} -- User and user talk }, { name = 'Protected images', type = 'edit', level = 'sysop', ns = {[6] = true} -- File }, { name = 'Protected project pages', type = 'edit', level = 'sysop', ns = {[4] = true, [12] = true} -- Project and Help }, { name = 'Wikipedia protected templates', type = 'edit', level = 'sysop', ns = {[10] = true}, -- Template }, { name = 'Protected talk pages', type = 'edit', level = 'sysop', ns = {talk = true} }, { name = 'Wikipedia pages protected against vandalism', type = 'edit', level = 'sysop', reason = 'vandalism' }, { name = 'Wikipedia pages semi-protected due to dispute', type = 'edit', level = 'autoconfirmed', reason = 'dispute' }, { name = 'Wikipedia pages protected due to dispute', type = 'edit', level = 'sysop', reason = 'dispute' }, { name = 'Wikipedia pages move-protected due to dispute', type = 'move', level = 'sysop', reason = 'dispute' }, { name = 'Wikipedia move-protected user and user talk pages', type = 'move', level = 'sysop', ns = {[2] = true, [3] = true} -- User and user talk }, { name = 'Wikipedia move-protected project pages', type = 'move', level = 'sysop', ns = {[4] = true} -- Project }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'sysop', ns = {[100] = true} -- Portal }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'autoconfirmed', ns = {[10] = true} -- Template }, { name = 'Wikipedia move-protected templates', type = 'move', level = 'sysop', ns = {[10] = true} -- Template }, { name = 'Wikipedia protected templates', type = 'edit', ns = {[10] = true} -- Template }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'sysop', ns = {[100] = true} -- Portal }, { name = 'Wikipedia pages semi-protected from banned users', type = 'edit', level = 'autoconfirmed', reason = 'sock' }, { name = 'Wikipedia pages protected from banned users', type = 'edit', level = 'sysop', reason = 'sock' }, { name = 'Wikipedia temporarily semi-protected biographies of living people', type = 'edit', level = 'autoconfirmed', reason = 'blp', expiry = 'temp' }, { name = 'Wikipedia temporarily protected biographies of living people', type = 'edit', level = 'sysop', reason = 'blp', expiry = 'temp' }, { name = 'Wikipedia indefinitely semi-protected biographies of living people', type = 'edit', level = 'autoconfirmed', reason = 'blp', expiry = 'indef' }, { name = 'Wikipedia indefinitely protected biographies of living people', type = 'edit', level = 'sysop', reason = 'blp', expiry = 'indef' }, { name = 'Wikipedia indefinitely semi-protected pages', type = 'edit', level = 'autoconfirmed', expiry = 'indef' }, { name = 'Wikipedia move-protected talk pages', type = 'move', level = 'sysop', ns = {talk = true} }, { name = 'Wikipedia indefinitely move-protected pages', type = 'move', level = 'sysop', expiry = 'indef' }, { name = 'Wikipedia semi-protected pages', type = 'edit', level = 'autoconfirmed' }, { name = 'Wikipedia protected pages', }, { name = 'Wikipedia semi-protected categories', type = 'edit', level = 'autoconfirmed', ns = {[14] = true} }, { name = 'Wikipedia protected categories', type = 'edit', ns = {[14] = true} -- Category }, { name = 'Wikipedia move-protected pages', type = 'move', level = 'sysop' }, { name = 'Wikipedia Office-protected pages', reason = 'office' }, { name = 'Wikipedia pending changes protected pages (level 1)', type = 'pc', level = 'autoconfirmed' }, { name = 'Wikipedia pending changes protected pages (level 2)', type = 'pc', level = 'reviewer' }, } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end return p 4lqwki0vy5v9qd92oezrqubdeean9zp 28067 28066 2014-03-03T15:40:22Z w>Mr. Stradivarius 0 add half-finished category sorting code 28067 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { { name = 'Wikipedia semi-protected user and user talk pages', type = 'edit', level = 'autoconfirmed', ns = {[2] = true, [3] = true} -- User and user talk }, { name = 'Semi-protected project pages', type = 'edit', level = 'autoconfirmed', ns = {[4] = true} -- Project }, { name = 'Semi-protected images', type = 'edit', level = 'autoconfirmed', ns = {[6] = true} -- File }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'autoconfirmed', ns = {[10] = true} -- Template }, { name = 'Semi-protected portals', type = 'edit', level = 'autoconfirmed', ns = {[100] = true} -- Portal }, { name = 'Semi-protected talk pages', type = 'edit', level = 'autoconfirmed', ns = {talk = true} }, { name = 'Wikipedia pages semi-protected against vandalism', type = 'edit', level = 'autoconfirmed', reason = 'vandalism' }, { name = 'Wikipedia protected user and user talk pages', type = 'edit', level = 'sysop', ns = {[2] = true, [3] = true} -- User and user talk }, { name = 'Protected images', type = 'edit', level = 'sysop', ns = {[6] = true} -- File }, { name = 'Protected project pages', type = 'edit', level = 'sysop', ns = {[4] = true, [12] = true} -- Project and Help }, { name = 'Wikipedia protected templates', type = 'edit', level = 'sysop', ns = {[10] = true}, -- Template }, { name = 'Protected talk pages', type = 'edit', level = 'sysop', ns = {talk = true} }, { name = 'Wikipedia pages protected against vandalism', type = 'edit', level = 'sysop', reason = 'vandalism' }, { name = 'Wikipedia pages semi-protected due to dispute', type = 'edit', level = 'autoconfirmed', reason = 'dispute' }, { name = 'Wikipedia pages protected due to dispute', type = 'edit', level = 'sysop', reason = 'dispute' }, { name = 'Wikipedia pages move-protected due to dispute', type = 'move', level = 'sysop', reason = 'dispute' }, { name = 'Wikipedia move-protected user and user talk pages', type = 'move', level = 'sysop', ns = {[2] = true, [3] = true} -- User and user talk }, { name = 'Wikipedia move-protected project pages', type = 'move', level = 'sysop', ns = {[4] = true} -- Project }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'sysop', ns = {[100] = true} -- Portal }, { name = 'Wikipedia semi-protected templates', type = 'edit', level = 'autoconfirmed', ns = {[10] = true} -- Template }, { name = 'Wikipedia move-protected templates', type = 'move', level = 'sysop', ns = {[10] = true} -- Template }, { name = 'Wikipedia protected templates', type = 'edit', ns = {[10] = true} -- Template }, { name = 'Wikipedia move-protected portals', type = 'move', level = 'sysop', ns = {[100] = true} -- Portal }, { name = 'Wikipedia pages semi-protected from banned users', type = 'edit', level = 'autoconfirmed', reason = 'sock' }, { name = 'Wikipedia pages protected from banned users', type = 'edit', level = 'sysop', reason = 'sock' }, { name = 'Wikipedia temporarily semi-protected biographies of living people', type = 'edit', level = 'autoconfirmed', reason = 'blp', expiry = 'temp' }, { name = 'Wikipedia temporarily protected biographies of living people', type = 'edit', level = 'sysop', reason = 'blp', expiry = 'temp' }, { name = 'Wikipedia indefinitely semi-protected biographies of living people', type = 'edit', level = 'autoconfirmed', reason = 'blp', expiry = 'indef' }, { name = 'Wikipedia indefinitely protected biographies of living people', type = 'edit', level = 'sysop', reason = 'blp', expiry = 'indef' }, { name = 'Wikipedia indefinitely semi-protected pages', type = 'edit', level = 'autoconfirmed', expiry = 'indef' }, { name = 'Wikipedia move-protected talk pages', type = 'move', level = 'sysop', ns = {talk = true} }, { name = 'Wikipedia indefinitely move-protected pages', type = 'move', level = 'sysop', expiry = 'indef' }, { name = 'Wikipedia semi-protected pages', type = 'edit', level = 'autoconfirmed' }, { name = 'Wikipedia protected pages', }, { name = 'Wikipedia semi-protected categories', type = 'edit', level = 'autoconfirmed', ns = {[14] = true} }, { name = 'Wikipedia protected categories', type = 'edit', ns = {[14] = true} -- Category }, { name = 'Wikipedia move-protected pages', type = 'move', level = 'sysop' }, { name = 'Wikipedia Office-protected pages', reason = 'office' }, { name = 'Wikipedia pending changes protected pages (level 1)', type = 'pc', level = 'autoconfirmed' }, { name = 'Wikipedia pending changes protected pages (level 2)', type = 'pc', level = 'reviewer' }, } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.matchCategory(cats, protType, protLevel, namespace, expiry, reason) local function isValidCat(t) --[[ -- Does a first parse over the categories, removing any that explicitly -- name a wrong parameter. This accounts for the majority of all of the -- categories. -- -- We check the parameters most likely to be wrong first. This saves on -- table lookups, which shoud make the function faster. --]] local testType, testLevel, testNs, testExpiry, testReason testReason = t.reason if testReason and testReason ~= reason then return false end testNs = t.namespace if testNs and not testNs[namespace] then return false end testExpiry = t.expiry if testExpiry and testExpiry ~= expiry then return false end testLevel = t.level if testLevel and testLevel ~= protLevel then return false end testType = t.type if testType and testType ~= protType then return false end return true end -- Remove invalid cats. local sortCats = {} for i, t in ipairs(cats) do if isValidCat(t) then sortCats[#sortCats + 1] = t end end -- Sort the remaining cats. -- The categories which are left either explicitly name the right parameter, -- or implicitly allow all values for that parameter. table.sort(sortCats, function (t1, t2) local type1 = t1.type local type2 = t2.type local level1 = t1.level local level2 = t2.level local ns1 = t1.namespace local ns2 = t2.namespace local exp1 = t1.expiry local exp2 = t2.expiry local reason1 = t1.reason local reason2 = t2.reason local score1 = 0 local score2 = 0 end) end return p oeao5d5xzgffc32xxdxqgqqwmonq0dq 28068 28067 2014-03-03T23:35:46Z w>Mr. Stradivarius 0 convert categories back to a flat table scheme 28068 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-user-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-all-all-all'] = 'Wikipedia protected categories', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.matchCategory(cats, protType, protLevel, namespace, expiry, reason) local function isValidCat(t) --[[ -- Does a first parse over the categories, removing any that explicitly -- name a wrong parameter. This accounts for the majority of all of the -- categories. -- -- We check the parameters most likely to be wrong first. This saves on -- table lookups, which shoud make the function faster. --]] local testType, testLevel, testNs, testExpiry, testReason testReason = t.reason if testReason and testReason ~= reason then return false end testNs = t.namespace if testNs and not testNs[namespace] then return false end testExpiry = t.expiry if testExpiry and testExpiry ~= expiry then return false end testLevel = t.level if testLevel and testLevel ~= protLevel then return false end testType = t.type if testType and testType ~= protType then return false end return true end -- Remove invalid cats. local sortCats = {} for i, t in ipairs(cats) do if isValidCat(t) then sortCats[#sortCats + 1] = t end end -- Sort the remaining cats. -- The categories which are left either explicitly name the right parameter, -- or implicitly allow all values for that parameter. table.sort(sortCats, function (t1, t2) local type1 = t1.type local type2 = t2.type local level1 = t1.level local level2 = t2.level local ns1 = t1.namespace local ns2 = t2.namespace local exp1 = t1.expiry local exp2 = t2.expiry local reason1 = t1.reason local reason2 = t2.reason local score1 = 0 local score2 = 0 end) end return p nhwl71il4lswhffvbln5lh1i22f9i82 28069 28068 2014-03-03T23:48:40Z w>Mr. Stradivarius 0 add namespace parser 28069 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-user-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-all-all-all'] = 'Wikipedia protected categories', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' else nskey = 'all' end return nskey end function p.matchCategory(cats, protType, protLevel, namespace, expiry, reason) local nskey = p.parseNamespace(namespace) end return p egyjfsmdirymtn7m20nqzwsvwz4twfe 28070 28069 2014-03-04T01:51:44Z w>Mr. Stradivarius 0 expand category matching code - still buggy 28070 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-user-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-all-all-all'] = 'Wikipedia protected categories', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.matchCategory(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local tryOrder = {5, 4, 3, 2, 1} -- Try successively generic matches until we run out of key combinations local function attemptMatch() local key = table.concat(keyTable, '-') mw.log(key) -- for debugging return cats[key] end local attempt = attemptMatch() if attempt then return attempt end for i, keyTableKey in ipairs(tryOrder) do keyTable[keyTableKey] = 'all' attempt = attemptMatch() if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p ln83bko6fpng0kz3vuczwscr5f5lbmu 28071 28070 2014-03-04T05:25:27Z w>Mr. Stradivarius 0 rename the category function as "getCategoryName" 28071 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-user-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-all-all-all'] = 'Wikipedia protected categories', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local tryOrder = {5, 4, 3, 2, 1} -- Try successively generic matches until we run out of key combinations local function attemptMatch() local key = table.concat(keyTable, '-') mw.log(key) -- for debugging return cats[key] end local attempt = attemptMatch() if attempt then return attempt end for i, keyTableKey in ipairs(tryOrder) do keyTable[keyTableKey] = 'all' attempt = attemptMatch() if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p kb3mdy5usl3usqav3rkdoy38b4fhaxm 28072 28071 2014-03-04T05:36:00Z w>Mr. Stradivarius 0 use "semi" instead of "autoconfirmed", to save typing time 28072 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-all-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local tryOrder = {5, 4, 3, 2, 1} -- Try successively generic matches until we run out of key combinations local function attemptMatch() local key = table.concat(keyTable, '-') mw.log(key) -- for debugging return cats[key] end local attempt = attemptMatch() if attempt then return attempt end for i, keyTableKey in ipairs(tryOrder) do keyTable[keyTableKey] = 'all' attempt = attemptMatch() if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 3vp590hzz7cevporr00oo1y2fy0dln4 28073 28072 2014-03-04T05:42:25Z w>Mr. Stradivarius 0 add an error cat 28073 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-all-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local tryOrder = {5, 4, 3, 2, 1} -- Try successively generic matches until we run out of key combinations local function attemptMatch() local key = table.concat(keyTable, '-') mw.log(key) -- for debugging return cats[key] end local attempt = attemptMatch() if attempt then return attempt end for i, keyTableKey in ipairs(tryOrder) do keyTable[keyTableKey] = 'all' attempt = attemptMatch() if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p cybp49ywvau3mwnzqzv1mpyd793bfed 28074 28073 2014-03-04T06:35:46Z w>Mr. Stradivarius 0 remove log message 28074 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-all-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local tryOrder = {5, 4, 3, 2, 1} -- Try successively generic matches until we run out of key combinations local function attemptMatch() local key = table.concat(keyTable, '-') return cats[key] end local attempt = attemptMatch() if attempt then return attempt end for i, keyTableKey in ipairs(tryOrder) do keyTable[keyTableKey] = 'all' attempt = attemptMatch() if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p s0lnt90pzh23s2dyducfpl0w4cp6dfr 28075 28074 2014-03-04T23:36:06Z w>Mr. Stradivarius 0 try a different order 28075 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-all-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local tryOrder = {5, 3, 4, 2, 1} -- Try successively generic matches until we run out of key combinations local function attemptMatch() local key = table.concat(keyTable, '-') return cats[key] end local attempt = attemptMatch() if attempt then return attempt end for i, keyTableKey in ipairs(tryOrder) do keyTable[keyTableKey] = 'all' attempt = attemptMatch() if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 9n39hpv2fl39lmwwo5nme1agthiwbre 28076 28075 2014-03-04T23:50:32Z w>Mr. Stradivarius 0 try different orders for vandalism and other reasons 28076 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-all-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local tryOrder if reason == 'vandalism' then tryOrder = {5, 4, 3, 2, 1} else tryOrder = {5, 3, 4, 2, 1} end -- Try successively generic matches until we run out of key combinations local function attemptMatch() local key = table.concat(keyTable, '-') return cats[key] end local attempt = attemptMatch() if attempt then return attempt end for i, keyTableKey in ipairs(tryOrder) do keyTable[keyTableKey] = 'all' attempt = attemptMatch() if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p b3z904vju0crfbd67lfe8b3x0z50u2l 28077 28076 2014-03-05T00:04:18Z w>Mr. Stradivarius 0 fix "Wikipedia protected categories" key 28077 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local tryOrder if reason == 'vandalism' then tryOrder = {5, 4, 3, 2, 1} else tryOrder = {5, 3, 4, 2, 1} end -- Try successively generic matches until we run out of key combinations local function attemptMatch() local key = table.concat(keyTable, '-') return cats[key] end local attempt = attemptMatch() if attempt then return attempt end for i, keyTableKey in ipairs(tryOrder) do keyTable[keyTableKey] = 'all' attempt = attemptMatch() if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p mp6avb740diu46lwevgmt9ybuzqzdqh 28078 28077 2014-03-05T00:35:06Z w>Mr. Stradivarius 0 try a different category matching algorithm completely 28078 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { {true, true, true, true, true}, {true, true, true, true, false}, {true, true, true, false, true}, {true, true, false, true, true}, {true, true, true, false, false}, {true, true, false, true, false}, {true, true, false, false, true}, {true, true, false, false, false}, {true, false, false, false, false}, {false, false, false, false, false} } -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j = 1, 5 do if t[j] then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p rhlam7qz0i3mnpn4rvnmj6ptphl40ky 28079 28078 2014-03-05T00:41:55Z w>Mr. Stradivarius 0 try adding an exception 28079 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, false, true, true}, -- 4 {true, true, true, false, false}, -- 5 {true, true, false, true, false}, -- 6 {true, true, false, false, true}, -- 7 {true, true, false, false, false}, -- 8 {true, false, false, false, false}, -- 9 {false, false, false, false, false} -- 10 } if reason == 'vandalism' then attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j = 1, 5 do if t[j] then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p pjqfprc8j3798hnu3nssanogz59na1h 28080 28079 2014-03-05T00:47:57Z w>Mr. Stradivarius 0 wrong way round? 28080 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, false, true, true}, -- 4 {true, true, true, false, false}, -- 5 {true, true, false, true, false}, -- 6 {true, true, false, false, true}, -- 7 {true, true, false, false, false}, -- 8 {true, false, false, false, false}, -- 9 {false, false, false, false, false} -- 10 } if reason ~= 'vandalism' then attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j = 1, 5 do if t[j] then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 29n2x1ykuwdal3x6zgrxvqi1ywwbrt1 28081 28080 2014-03-05T00:57:01Z w>Mr. Stradivarius 0 use ipairs to make the attempt loop a little more efficient 28081 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-user-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, false, true, true}, -- 4 {true, true, true, false, false}, -- 5 {true, true, false, true, false}, -- 6 {true, true, false, false, true}, -- 7 {true, true, false, false, false}, -- 8 {true, false, false, false, false}, -- 9 {false, false, false, false, false} -- 10 } if reason ~= 'vandalism' then attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p a0af6lzbyzknoot9kpur1crdfwuw6vf 28082 28081 2014-03-05T01:36:57Z w>Mr. Stradivarius 0 various category table fixes 28082 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-project-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['move-full-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, false, true, true}, -- 4 {true, true, true, false, false}, -- 5 {true, true, false, true, false}, -- 6 {true, true, false, false, true}, -- 7 {true, true, false, false, false}, -- 8 {true, false, false, false, false}, -- 9 {false, false, false, false, false} -- 10 } if reason ~= 'vandalism' then attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p h97unp6hmo3k7sn0151b87m1i5bb0mp 28083 28082 2014-03-06T02:03:09Z w>Mr. Stradivarius 0 add extra step to detect template-protected templates 28083 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-project-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['move-full-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-indef'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-indef'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, false, true, true}, -- 4 {true, true, true, false, false}, -- 5 {true, true, false, true, false}, -- 6 {true, true, false, false, true}, -- 7 {true, true, false, false, false}, -- 8 {true, false, true, false, false}, -- 9 {true, false, false, false, false}, -- 10 {false, false, false, false, false} -- 11 } if reason ~= 'vandalism' then attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 18r39mu9w803an63309nroxo1c9ahph 28084 28083 2014-03-06T02:42:38Z w>Mr. Stradivarius 0 make indef blp categories work for 'all' as well as 'indef' 28084 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-project-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['move-full-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, false, true, true}, -- 4 {true, true, true, false, false}, -- 5 {true, true, false, true, false}, -- 6 {true, true, false, false, true}, -- 7 {true, true, false, false, false}, -- 8 {true, false, true, false, false}, -- 9 {true, false, false, false, false}, -- 10 {false, false, false, false, false} -- 11 } if reason ~= 'vandalism' then attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 4yd9v56abni9sa93qwj0n7g7u59gxvw 28085 28084 2014-03-06T06:01:00Z w>Mr. Stradivarius 0 try fairly ugly hack for office protection 28085 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-semi-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-semi-project-all-all'] = 'Semi-protected project pages', ['edit-semi-file-all-all'] = 'Semi-protected images', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-semi-portal-all-all'] = 'Semi-protected portals', ['edit-semi-talk-all-all'] = 'Semi-protected talk pages', ['edit-semi-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-full-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-full-file-all-all'] = 'Protected images', ['edit-full-project-all-all'] = 'Protected project pages', ['edit-full-template-all-all'] = 'Wikipedia protected templates', ['edit-full-talk-all-all'] = 'Protected talk pages', ['edit-full-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-semi-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-full-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-full-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-full-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-full-project-all-all'] = 'Wikipedia move-protected project pages', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['move-full-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-semi-template-all-all'] = 'Wikipedia semi-protected templates', ['move-full-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-full-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-semi-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-full-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-semi-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-full-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-semi-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-full-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-semi-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-full-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-full-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-semi-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-semi-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-full-category-all-all'] = 'Wikipedia protected categories', ['move-full-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-semi-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, true, false, true}, -- 4 {true, true, false, true, false}, -- 5 {true, true, true, false, false}, -- 6 {true, true, false, false, true}, -- 7 {true, true, false, false, false}, -- 8 {true, false, true, false, false}, -- 9 {true, false, false, false, false}, -- 10 {false, false, false, false, false} -- 11 } local reasonFirst = { vandalism = true, office = true } if reasonFirst[reason] then attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] table.insert(attemptOrder, 2, {false, false, false, true, false}) -- To deal with office-protection end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p sjlipkwh6hf9wqrje9nxraw7e21zq00 28086 28085 2014-03-06T06:26:00Z w>Mr. Stradivarius 0 use the default mediawiki protection level names after all 28086 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, true, false, true}, -- 4 {true, true, false, true, false}, -- 5 {true, true, true, false, false}, -- 6 {true, true, false, false, true}, -- 7 {true, true, false, false, false}, -- 8 {true, false, true, false, false}, -- 9 {true, false, false, false, false}, -- 10 {false, false, false, false, false} -- 11 } local reasonFirst = { vandalism = true, office = true } if reasonFirst[reason] then attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] table.insert(attemptOrder, 2, {false, false, false, true, false}) -- To deal with office-protection end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p pdvx0yjc4jcm2c2r290qtas56b9f5e1 28087 28086 2014-03-06T07:07:57Z w>Mr. Stradivarius 0 try making the algorithm more general 28087 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['office'] = 'Wikipedia Office-protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, true, false, true}, -- 4 {true, true, false, true, false}, -- 5 {true, true, true, false, false}, -- 6 {true, true, false, false, true}, -- 7 {true, false, true, true, true}, -- 8 {true, false, true, true, false}, -- 9 {true, false, false, true, true}, -- 10 {true, false, true, false, true}, -- 11 {true, false, false, true, false}, -- 12 {true, false, true, false, false}, -- 13 {true, false, false, false, true}, -- 14 {true, false, false, false, false}, -- 15 {false, false, false, false, false} -- 16 } local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonOnly', } local reasonBehavior = reasonBehaviors[reason] if reasonBehavior == 'reasonOnly' then local attempt = cats[reason] if attempt then return attempt else error('the category for key "' .. reason .. '" is undefined') end elseif reasonBehavior == 'namespaceFirst' then -- Sort the order so that namespace keys are checked before reason matches. attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] elseif not reasonBeavior then error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 4wycr35qq82iympzvct9e3nj3ag4q2n 28088 28087 2014-03-06T07:09:53Z w>Mr. Stradivarius 0 fix typo 28088 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['office'] = 'Wikipedia Office-protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, true, false, true}, -- 4 {true, true, false, true, false}, -- 5 {true, true, true, false, false}, -- 6 {true, true, false, false, true}, -- 7 {true, false, true, true, true}, -- 8 {true, false, true, true, false}, -- 9 {true, false, false, true, true}, -- 10 {true, false, true, false, true}, -- 11 {true, false, false, true, false}, -- 12 {true, false, true, false, false}, -- 13 {true, false, false, false, true}, -- 14 {true, false, false, false, false}, -- 15 {false, false, false, false, false} -- 16 } local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonOnly', } local reasonBehavior = reasonBehaviors[reason] if reasonBehavior == 'reasonOnly' then local attempt = cats[reason] if attempt then return attempt else error('the category for key "' .. reason .. '" is undefined') end elseif reasonBehavior == 'namespaceFirst' then -- Sort the order so that namespace keys are checked before reason matches. attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] elseif not reasonBehavior then error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 5qoq2j6xhfqyera5ckhxumdw44b4a18 28089 28088 2014-03-06T07:11:59Z w>Mr. Stradivarius 0 add a check for the 'all' keyword 28089 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['office'] = 'Wikipedia Office-protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, true, false, true}, -- 4 {true, true, false, true, false}, -- 5 {true, true, true, false, false}, -- 6 {true, true, false, false, true}, -- 7 {true, false, true, true, true}, -- 8 {true, false, true, true, false}, -- 9 {true, false, false, true, true}, -- 10 {true, false, true, false, true}, -- 11 {true, false, false, true, false}, -- 12 {true, false, true, false, false}, -- 13 {true, false, false, false, true}, -- 14 {true, false, false, false, false}, -- 15 {false, false, false, false, false} -- 16 } local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonOnly', } local reasonBehavior = reasonBehaviors[reason] if reasonBehavior == 'reasonOnly' then local attempt = cats[reason] if attempt then return attempt else error('the category for key "' .. reason .. '" is undefined') end elseif reasonBehavior == 'namespaceFirst' then -- Sort the order so that namespace keys are checked before reason matches. attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] elseif not reasonBehavior or reasonBehavior ~= 'all' then error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p e0d9ckt5k3x10vwbc8a42ra5ql6xqvx 28090 28089 2014-03-06T10:55:23Z w>Mr. Stradivarius 0 logic fix 28090 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['office'] = 'Wikipedia Office-protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, true, false, true}, -- 4 {true, true, false, true, false}, -- 5 {true, true, true, false, false}, -- 6 {true, true, false, false, true}, -- 7 {true, false, true, true, true}, -- 8 {true, false, true, true, false}, -- 9 {true, false, false, true, true}, -- 10 {true, false, true, false, true}, -- 11 {true, false, false, true, false}, -- 12 {true, false, true, false, false}, -- 13 {true, false, false, false, true}, -- 14 {true, false, false, false, false}, -- 15 {false, false, false, false, false} -- 16 } local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonOnly', } local reasonBehavior = reasonBehaviors[reason] if reasonBehavior == 'reasonOnly' then local attempt = cats[reason] if attempt then return attempt else error('the category for key "' .. reason .. '" is undefined') end elseif reasonBehavior == 'namespaceFirst' then -- Sort the order so that namespace keys are checked before reason matches. attemptOrder[3], attemptOrder[4] = attemptOrder[4], attemptOrder[3] attemptOrder[5], attemptOrder[6] = attemptOrder[6], attemptOrder[5] elseif reasonBehavior ~= 'reasonFirst' and reason ~= 'all' then error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p d4kieef7lk1die4xs8m26f1vqh845pf 28091 28090 2014-03-06T11:15:00Z w>Mr. Stradivarius 0 see if this is possible with just two options 28091 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-all-all'] = 'Wikipedia protected pages', ['office'] = 'Wikipedia Office-protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } local reasonBehavior = reasonBehaviors[reason] local attemptOrder if reasonBehavior == 'reasonFirst' then attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, false, true, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, false, true, true}, -- 7 {true, false, false, true, false}, -- 8 {false, false, false, true, false}, -- 9 {true, true, true, false, true}, -- 10 {true, true, true, false, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, true, false, true}, -- 13 {true, false, true, false, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } elseif reasonBehavior == 'namespaceFirst' then attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, true, false, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, true, false, true}, -- 7 {true, false, true, false, false}, -- 8 {false, false, true, false, false}, -- 9 {true, true, false, true, true}, -- 10 {true, true, false, true, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, false, true, true}, -- 13 {true, false, false, true, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } elseif reason ~= 'all' then error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 0c0vefo2kxf5sn1vjs37e75z84lcy6d 28092 28091 2014-03-06T11:20:48Z w>Mr. Stradivarius 0 fix logic for reasonBehavior == 'all' and fix the office protection category key 28092 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } local template_types = { vandalism = { namespaces = false, -- defaults to all namespaces editLevels = false, -- all edit protection levels moveLevels = false, -- all move protection levels createLevels = false, -- all create protection levels header = false, reason = 'due to [[Wikipedia:Vandalism|vandalism]]', icon_reason = 'due to vandalism', } } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local p = {} function p.main(frame) -- Get data local args = getArgs(frame) local title = p.getTitle(args.page) local protType, protLevel = p.getProtectionStatus(title) local namespace = p.getNamespace(title) local expiry = p.getExpiry(args.expiry) local reason = p.getReason(args.reason) -- Sort categories and build a category link with the best match categories = p.sortCategories(categories, protType, protLevel, namespace, expiry, reason) local category = categories[1].name category = string.format('[[Category:%s]]', category) -- Find whether we are small or not and output a padlock or a banner as appropriate local isSmall = yesno(args.small, true) if isSmall then return p.exportPadlock() else return p.exportBanner() end end function p.parseNamespace(ns) -- The ns variable is the namespace number. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.parseNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end -- Define the key table and the order to test it in. -- This part is a little like playing regex golf - we have to make up a new -- rule for every idiosyncracy that was in the old template system. local keyTable = {protType, protLevel, namespace, reason, expiry} local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } local reasonBehavior = reasonBehaviors[reason] local attemptOrder if reasonBehavior == 'namespaceFirst' then attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, true, false, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, true, false, true}, -- 7 {true, false, true, false, false}, -- 8 {false, false, true, false, false}, -- 9 {true, true, false, true, true}, -- 10 {true, true, false, true, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, false, true, true}, -- 13 {true, false, false, true, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } elseif reasonBehavior == 'reasonFirst' or reason == 'all' then attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, false, true, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, false, true, true}, -- 7 {true, false, false, true, false}, -- 8 {false, false, false, true, false}, -- 9 {true, true, true, false, true}, -- 10 {true, true, true, false, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, true, false, true}, -- 13 {true, false, true, false, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } else error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useKeyTable in ipairs(t) do if useKeyTable then key[j] = keyTable[j] else key[j] = 'all' end end key = table.concat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p gz3cc42xs099cilejgybwwr4blmc7uh 28093 28092 2014-03-10T14:47:31Z w>Mr. Stradivarius 0 tidy this up and comment it so it will be easier for others to understand 28093 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespacep parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.matchNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end --[[ -- Define the key table and the order to test it in. -- The idiosyncracies of the old template system have been distilled down to -- two basic behaviors - templates that prioritise matching the reason over -- matching the namespace, and templates that prioritise matching the -- namespace over matching the reason. In each case the function tries to -- match specific keys, and if there is no match, it proceeds to match -- increasingly generic keys, until eventually it will match the key -- "all-all-all-all-all". --]] local protectionProperties = {protType, protLevel, namespace, reason, expiry} local reasonBehavior = reasonBehaviors[reason] local attemptOrder if reasonBehavior == 'namespaceFirst' then attemptOrder = { -- type, level, ns, reason, expiry -- true corresponds to the original protectionProperties key, -- and false corresponds to the key "all". {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, true, false, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, true, false, true}, -- 7 {true, false, true, false, false}, -- 8 {false, false, true, false, false}, -- 9 {true, true, false, true, true}, -- 10 {true, true, false, true, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, false, true, true}, -- 13 {true, false, false, true, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } elseif reasonBehavior == 'reasonFirst' or reason == 'all' then attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, false, true, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, false, true, true}, -- 7 {true, false, false, true, false}, -- 8 {false, false, false, true, false}, -- 9 {true, true, true, false, true}, -- 10 {true, true, true, false, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, true, false, true}, -- 13 {true, false, true, false, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } else error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useProperty in ipairs(t) do if useProperty then key[j] = protectionProperties[j] else key[j] = 'all' end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 7l04g3slkfixaf67r0j1ec6ds5bahma 28094 28093 2014-03-10T14:55:09Z w>Mr. Stradivarius 0 fix comment typo 28094 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' elseif not nskey then nskey = 'all' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.matchNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end --[[ -- Define the key table and the order to test it in. -- The idiosyncracies of the old template system have been distilled down to -- two basic behaviors - templates that prioritise matching the reason over -- matching the namespace, and templates that prioritise matching the -- namespace over matching the reason. In each case the function tries to -- match specific keys, and if there is no match, it proceeds to match -- increasingly generic keys, until eventually it will match the key -- "all-all-all-all-all". --]] local protectionProperties = {protType, protLevel, namespace, reason, expiry} local reasonBehavior = reasonBehaviors[reason] local attemptOrder if reasonBehavior == 'namespaceFirst' then attemptOrder = { -- type, level, ns, reason, expiry -- true corresponds to the original protectionProperties key, -- and false corresponds to the key "all". {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, true, false, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, true, false, true}, -- 7 {true, false, true, false, false}, -- 8 {false, false, true, false, false}, -- 9 {true, true, false, true, true}, -- 10 {true, true, false, true, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, false, true, true}, -- 13 {true, false, false, true, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } elseif reasonBehavior == 'reasonFirst' or reason == 'all' then attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, false, true, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, false, true, true}, -- 7 {true, false, false, true, false}, -- 8 {false, false, false, true, false}, -- 9 {true, true, true, false, true}, -- 10 {true, true, true, false, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, true, false, true}, -- 13 {true, false, true, false, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } else error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useProperty in ipairs(t) do if useProperty then key[j] = protectionProperties[j] else key[j] = 'all' end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p tfo6scetuahby04hilsqetkgbt62dp1 28095 28094 2014-03-11T00:25:09Z w>Mr. Stradivarius 0 more efficient p.matchNamespace logic 28095 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local reasonBehaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey then if ns % 2 == 1 then nskey = 'talk' else nskey = 'all' end end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.matchNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end --[[ -- Define the key table and the order to test it in. -- The idiosyncracies of the old template system have been distilled down to -- two basic behaviors - templates that prioritise matching the reason over -- matching the namespace, and templates that prioritise matching the -- namespace over matching the reason. In each case the function tries to -- match specific keys, and if there is no match, it proceeds to match -- increasingly generic keys, until eventually it will match the key -- "all-all-all-all-all". --]] local protectionProperties = {protType, protLevel, namespace, reason, expiry} local reasonBehavior = reasonBehaviors[reason] local attemptOrder if reasonBehavior == 'namespaceFirst' then attemptOrder = { -- type, level, ns, reason, expiry -- true corresponds to the original protectionProperties key, -- and false corresponds to the key "all". {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, true, false, true}, -- 3 {true, true, true, false, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, true, false, true}, -- 7 {true, false, true, false, false}, -- 8 {false, false, true, false, false}, -- 9 {true, true, false, true, true}, -- 10 {true, true, false, true, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, false, true, true}, -- 13 {true, false, false, true, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } elseif reasonBehavior == 'reasonFirst' or reason == 'all' then attemptOrder = { -- type, level, ns, reason, expiry {true, true, true, true, true}, -- 1 {true, true, true, true, false}, -- 2 {true, true, false, true, true}, -- 3 {true, true, false, true, false}, -- 4 {true, false, true, true, true}, -- 5 {true, false, true, true, false}, -- 6 {true, false, false, true, true}, -- 7 {true, false, false, true, false}, -- 8 {false, false, false, true, false}, -- 9 {true, true, true, false, true}, -- 10 {true, true, true, false, false}, -- 11 {true, true, false, false, true}, -- 12 {true, false, true, false, true}, -- 13 {true, false, true, false, false}, -- 14 {true, false, false, false, true}, -- 15 {true, false, false, false, false}, -- 16 {false, false, false, false, false} -- 17 } else error(reason .. ' is not a valid reason') end -- Try successively generic matches until we run out of key combinations for i, t in ipairs(attemptOrder) do local key = {} for j, useProperty in ipairs(t) do if useProperty then key[j] = protectionProperties[j] else key[j] = 'all' end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 9p1cgqzylic1k076i68paicjb0hrixl 28096 28095 2014-03-11T06:17:23Z w>Mr. Stradivarius 0 save progress in simplifying the attempt order algorithm 28096 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local floor = math.floor local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey then if ns % 2 == 1 then nskey = 'talk' else nskey = 'all' end end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. -- Preprocess parameters cats = cats or categories protType = protType or 'all' protLevel = protLevel or 'all' namespace = p.matchNamespace(namespace) reason = reason or 'all' if not expiry then expiry = 'all' elseif expiry ~= 'indef' then expiry = 'temp' end local properties = {expiry, namespace, protLevel, protType, reason} local behavior = behaviors[reason] if behavior == 'namespaceFirst' then tinsert(properties, table.remove(properties, 2)) -- move namespace to the end elseif behavior ~= 'reasonFirst' and reason ~= 'all' then error(reason .. ' is not a valid reason') end local activeProperties = {} for i, property in ipairs(properties) do if property ~= 'all' then activeProperties[#activeProperties + 1] = property end end local noActiveProperties = #activeProperties -- Try successively generic matches until we run out of key combinations for i = 1, 2^noActiveProperties do local key = {} for pos = 1, 5 do if pos > noActiveProperties then key[pos] = 'all' else local quotient = i / 2 ^ (pos - 1) quotient = floor(quotient) if quotient % 2 == 1 then key[pos] = protectionProperties[j] else -- quotient % 2 == 0 key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p jb3aa74js6h9po7im1jqibfl8zr7rxw 28097 28096 2014-03-11T07:23:22Z w>Mr. Stradivarius 0 change this to something that should work if I can get the order figured out 28097 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local floor = math.floor local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return 'all' end local nskey = nskeys[ns] if not nskey then if ns % 2 == 1 then nskey = 'talk' else nskey = 'all' end end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. -- Preprocess parameters cats = cats or categories local properties = {} properties.protType = protType or 'all' properties.protLevel = protLevel or 'all' properties.namespace = p.matchNamespace(namespace) properties.reason = reason or 'all' if not expiry then properties.expiry = 'all' elseif expiry ~= 'indef' then properties.expiry = 'temp' end local order = {'expiry', 'namespace', 'protLevel', 'protType', 'reason'} local behavior = behaviors[reason] if behavior == 'namespaceFirst' then tinsert(order, table.remove(order, 2)) -- move namespace to the end elseif behavior ~= 'reasonFirst' and reason ~= 'all' then error(reason .. ' is not a valid reason') end local activePropertyKeys = {} for i, propertyKey in ipairs(order) do if properties[propertyKey] ~= 'all' then activePropertyKeys[#activePropertyKeys + 1] = propertyKey end end local noActiveProperties = #activePropertyKeys -- Try successively generic matches until we run out of key combinations for i = 1, 2^noActiveProperties do local categoryKey = {} for pos = 1, 5 do if pos > noActiveProperties then categoryKey[pos] = 'all' else local quotient = i / 2 ^ (pos - 1) quotient = floor(quotient) if quotient % 2 == 1 then categoryKey[pos] = properties[activePropertyKeys[pos]] else -- quotient % 2 == 0 categoryKey[pos] = 'all' end end end categoryKey = tconcat(categoryKey, '-') mw.log(categoryKey) -- for debugging local attempt = cats[categoryKey] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p ofkv77t9lhzv0jtzqz1cwpeno857bxr 28098 28097 2014-03-11T12:52:20Z w>Mr. Stradivarius 0 key components are in the correct order now - property order still a long way off, though 28098 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local floor = math.floor local function toTableEnd(t, pos) -- Sends the item at position pos to the end of array t, -- and shifts all the other array items down accordingly. tinsert(t, tremove(t, pos)) end local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. cats = cats or categories local properties = { {pos = 5, val = expiry}, {pos = 3, val = namespace}, {pos = 2, val = protLevel}, {pos = 1, val = protType}, {pos = 4, val = reason} } local behavior = 'reasonFirst' if reason then behavior = behaviors[reason] if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to the end elseif behavior ~= 'reasonFirst' then error(reason .. ' is not a valid reason') end end local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = floor(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 7k3geo2iu5gaeza9otesrq7h58pskxf 28099 28098 2014-03-11T13:17:37Z w>Mr. Stradivarius 0 should have been math.ceil, not math.floor 28099 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local function toTableEnd(t, pos) -- Sends the item at position pos to the end of array t, -- and shifts all the other array items down accordingly. tinsert(t, tremove(t, pos)) end local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. cats = cats or categories local properties = { {pos = 5, val = expiry}, {pos = 3, val = namespace}, {pos = 2, val = protLevel}, {pos = 1, val = protType}, {pos = 4, val = reason} } local behavior = 'reasonFirst' if reason then behavior = behaviors[reason] if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to the end elseif behavior ~= 'reasonFirst' then error(reason .. ' is not a valid reason') end end local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p fejh6u9kw6ejksdgxv42o37t0zv2tm9 28100 28099 2014-03-11T13:26:46Z w>Mr. Stradivarius 0 use p.matchNamespace 28100 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local function toTableEnd(t, pos) -- Sends the item at position pos to the end of array t, -- and shifts all the other array items down accordingly. tinsert(t, tremove(t, pos)) end local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. cats = cats or categories local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 2, val = protLevel}, {pos = 1, val = protType}, {pos = 4, val = reason} } local behavior = 'reasonFirst' if reason then behavior = behaviors[reason] if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to the end elseif behavior ~= 'reasonFirst' then error(reason .. ' is not a valid reason') end end local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p 6yes9rmihhdexcf85gwr0t7vt3af2h2 28101 28100 2014-03-11T15:01:38Z w>Mr. Stradivarius 0 add some lengthy comments explaining what's going on 28101 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local ceil = math.ceil local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 2, val = protLevel}, {pos = 1, val = protType}, {pos = 4, val = reason} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior = 'reasonFirst' if reason then behavior = behaviors[reason] if behavior == 'namespaceFirst' then table.insert(properties, table.remove(properties, 2)) elseif behavior ~= 'reasonFirst' then error(reason .. ' is not a valid reason') end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p tin3lokjhueo7gga5cnvozrxcl3b19g 28102 28101 2014-03-12T01:20:02Z w>Mr. Stradivarius 0 try tweaking the order 28102 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = behaviors[reason] end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end return p pkwpmxq90240pad49w058m0jug0xfr3 28103 28102 2014-03-12T03:21:21Z w>Mr. Stradivarius 0 add p.renderPadlock function 28103 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = behaviors[reason] end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderPadlock(data) -- Renders the padlock seen in the top-right-hand corner or protected pages, -- using the data provided in the data table. local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = data.right or '55px'} :wikitext(format( '[[Image:%s|20px|link=%s|%s|alt=%s]]', data.image, data.iconLink, data.iconText, data.altText )) return tostring(root) end return p gne121df18u3qotpi0yu2v2oudmk2m3 28104 28103 2014-03-12T05:19:48Z w>Mr. Stradivarius 0 add a p.renderBanner function 28104 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local nskeys = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = nskeys[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = behaviors[reason] end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderPadlock(data) --[[ -- Renders the padlock seen in the top-right-hand corner or protected pages, -- using the data provided in the data table. -- -- Data fields: -- data.right -- data.image -- data.iconLink -- data.iconText -- data.altText --]] local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = data.right or '55px'} :wikitext(format( '[[Image:%s|20px|link=%s|%s|alt=%s]]', data.image, data.iconLink, data.iconText, data.altText )) return tostring(root) end function p.renderBanner(data) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- Data fields: -- data.page -- data.image -- data.text --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = data.page, type = 'protection', image = data.image, text = data.text } return mMessageBox.main('mbox', mbargs) end return p h2s943x2psg0tvcj4p5w17h8cghe0ki 28105 28104 2014-03-12T05:39:22Z w>Mr. Stradivarius 0 add a p.getPagetype function 28105 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } local pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = behaviors[reason] end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderPadlock(data) --[[ -- Renders the padlock seen in the top-right-hand corner or protected pages, -- using the data provided in the data table. -- -- Data fields: -- data.right -- data.image -- data.iconLink -- data.iconText -- data.altText --]] local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = data.right or '55px'} :wikitext(format( '[[Image:%s|20px|link=%s|%s|alt=%s]]', data.image, data.iconLink, data.iconText, data.altText )) return tostring(root) end function p.renderBanner(data) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- Data fields: -- data.page -- data.image -- data.text --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = data.page, type = 'protection', image = data.image, text = data.text } return mMessageBox.main('mbox', mbargs) end return p hwg14lop22wg6camd4qwr0kl0v4nbv2 28106 28105 2014-03-16T10:36:03Z w>Mr. Stradivarius 0 add a p.renderImageLink function so that we can share image generation code between the padlock and the banner 28106 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-all-all'] = 'Wikipedia protected pages', } local categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } local pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = behaviors[reason] end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext -- right - the "right" css property value, as a string -- -- Both parameters are optional. --]] local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p j6qphoepl4raqyad3y0ph59fcrte34j 28107 28106 2014-03-16T10:41:37Z w>Mr. Stradivarius 0 beautify the categories table 28107 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } local categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } local behaviors = { vandalism = 'namespaceFirst', dispute = 'reasonFirst', blp = 'reasonFirst', sock = 'reasonFirst', office = 'reasonFirst', } local pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = behaviors[reason] end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext -- right - the "right" css property value, as a string -- -- Both parameters are optional. --]] local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p 64b6h61z4sons3kcbxk7i7vtykvh84n 28108 28107 2014-03-16T10:51:26Z w>Mr. Stradivarius 0 try different format for behaviors table 28108 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { behavior = 'reasonFirst' }, dispute = { behavior = 'reasonFirst' }, office = { behavior = 'reasonFirst' }, sock = { behavior = 'reasonFirst' }, vandalism = { behavior = 'namespaceFirst' }, } cfg.protectionLevels = { foo } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = cfg.reasons[reason].behavior end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext -- right - the "right" css property value, as a string -- -- Both parameters are optional. --]] local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p px4q1lxhoab86zpoh0yat5acsffap7a 28109 28108 2014-03-16T10:57:55Z w>Mr. Stradivarius 0 add custom error for p.renderPadlock 28109 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { behavior = 'reasonFirst' }, dispute = { behavior = 'reasonFirst' }, office = { behavior = 'reasonFirst' }, sock = { behavior = 'reasonFirst' }, vandalism = { behavior = 'namespaceFirst' }, } cfg.protectionLevels = { foo } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = cfg.reasons[reason].behavior end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image or error('No image parameter specified in p.renderPadlock')) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p b4jqejpa2m3o4x10vv3bz57xrp6joyl 28110 28109 2014-03-16T11:00:29Z w>Mr. Stradivarius 0 try doing the error check earlier 28110 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { behavior = 'reasonFirst' }, dispute = { behavior = 'reasonFirst' }, office = { behavior = 'reasonFirst' }, sock = { behavior = 'reasonFirst' }, vandalism = { behavior = 'namespaceFirst' }, } cfg.protectionLevels = { foo } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = cfg.reasons[reason].behavior end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') mw.log(key) -- for debugging local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p 8muds0i2l8pv8ppa2cu8qm3vvabuuij 28111 28110 2014-03-16T11:42:48Z w>Mr. Stradivarius 0 don't log the category keys - seems to be working well enough now 28111 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { behavior = 'reasonFirst' }, dispute = { behavior = 'reasonFirst' }, office = { behavior = 'reasonFirst' }, sock = { behavior = 'reasonFirst' }, vandalism = { behavior = 'namespaceFirst' }, } cfg.protectionLevels = { foo } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = cfg.reasons[reason].behavior end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p 6m9e8j3r3junfmiay4l6gw2lto8qts9 28112 28111 2014-03-16T14:31:59Z w>Mr. Stradivarius 0 make a tentative start to the problem of how to store the protection messages 28112 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link blp = { behavior = 'reasonFirst' }, dispute = { behavior = 'reasonFirst', reasonTemp = ' $1 editing $2 have been resolved' }, office = { behavior = 'reasonFirst' }, sock = { behavior = 'reasonFirst' }, vandalism = { behavior = 'namespaceFirst' }, } cfg.protectionLevels = { foo } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = cfg.reasons[reason].behavior end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p 5ztxvimfpbhg355it8bz5sfsa4tmjwt 28113 28112 2014-03-17T00:49:07Z w>Mr. Stradivarius 0 add some more blurbs 28113 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link blp = { behavior = 'reasonFirst' }, dispute = { behavior = 'reasonFirst', reason = '$1 editing $2 have been resolved', iconReason = 'due to editing disputes', dispute = true }, office = { behavior = 'reasonFirst' }, sock = { behavior = 'reasonFirst' }, vandalism = { behavior = 'namespaceFirst', reason = 'due to [[Wikipedia:Vandalism|vandalism]]', iconReason = 'due to vandalism' }, } cfg.protectionLevels = { foo } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, protType, protLevel, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { {pos = 5, val = expiry}, {pos = 3, val = p.matchNamespace(namespace)}, {pos = 4, val = reason}, {pos = 2, val = protLevel}, {pos = 1, val = protType} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local behavior if not reason then behavior = 'reasonFirst' else behavior = cfg.reasons[reason].behavior end if behavior == 'namespaceFirst' then toTableEnd(properties, 2) -- move namespace to end elseif behavior == 'reasonFirst' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p t9cgdivywvuy6l7tum10kx3bq24kfcr 28114 28113 2014-03-17T06:08:38Z w>Mr. Stradivarius 0 more data table restructuring, plus some fiddling around with the category name function; this is a progress save, so the code is horribly broken at the moment 28114 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { categoryOrder = 'reason', banner = 'blp' }, dispute = { categoryOrder = 'reason', banner = 'dispute' }, office = { categoryOrder = 'reason', banner = 'office' }, sock = { categoryOrder = 'reason', banner = 'sock' }, usertalk = { banner = 'usertalk' }, vandalism = { categoryOrder = 'namespace', banner = 'vandalism' } } cfg.banners = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link blp = { }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true }, office = { }, sock = { }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection#' .. 'Current requests for edits to a protected page|request an edit]],' .. ' [[Wikipedia:Requests for page protection#' .. 'Current requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].' }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism' }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the pos value in -- each subtable is the position of the value in the category key. --]] local properties = { expiry = {pos = 5, val = expiry}, namespace = {'namespace', pos = 3, val = p.matchNamespace(namespace)}, reason = {pos = 4, val = reason}, level = {pos = 2, val = level}, action = {pos = 1, val = action} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local categoryOrder if not reason then categoryOrder = 'reason' else categoryOrder = cfg.reasons[reason].categoryOrder end if categoryOrder == 'namespace' then toTableEnd(properties, 2) -- move namespace to end elseif categoryOrder == 'reason' then toTableEnd(properties, 3) -- move reason to end else error(reason .. ' is not a valid reason') end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(properties) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do local pos = t.pos local val = t.val if j > noActive then key[pos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[pos] = val else key[pos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p dxezcox4hzwzuiweb8p38b0eutyi4pn 28115 28114 2014-03-18T01:44:57Z w>Mr. Stradivarius 0 make the category attempt order more configurable 28115 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { categoryOrder = 'reason', banner = 'blp' }, dispute = { categoryOrder = 'reason', banner = 'dispute' }, office = { categoryOrder = 'reason', banner = 'office' }, sock = { categoryOrder = 'reason', banner = 'sock' }, usertalk = { banner = 'usertalk' }, vandalism = { categoryOrder = 'namespace', banner = 'vandalism' } } cfg.banners = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link blp = { }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true }, office = { }, sock = { }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection#' .. 'Current requests for edits to a protected page|request an edit]],' .. ' [[Wikipedia:Requests for page protection#' .. 'Current requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].' }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism' }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the initial order to test properties in. The subtable position -- is the order the properties will be tested in, and the keypos value in -- each subtable is the position of the value in the category key. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Validate reason, and if it is specified as a "namespaceFirst" reason, -- move the namespace subtable to the end of the properties table. -- This is necessary to accommodate reasons like "vandalism", as the old -- {{pp-vandalism}} template used namespace categories rather than -- vandalism categories if they were available. --]] local reasonTable = cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then error('no properties key') end local property = properties[propertiesKey] if not property then error('invalid properties key') end if dupes[property] then error('dupe detected') else dupes[property] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then error('invalid category order string') end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p azxvmxjelquzdyeeatfwf01vz2x928c 28116 28115 2014-03-18T03:39:12Z w>Mr. Stradivarius 0 fix category name function comments 28116 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { categoryOrder = 'reason', banner = 'blp' }, dispute = { categoryOrder = 'reason', banner = 'dispute' }, office = { categoryOrder = 'reason', banner = 'office' }, sock = { categoryOrder = 'reason', banner = 'sock' }, usertalk = { banner = 'usertalk' }, vandalism = { categoryOrder = 'namespace', banner = 'vandalism' } } cfg.banners = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link blp = { }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true }, office = { }, sock = { }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection#' .. 'Current requests for edits to a protected page|request an edit]],' .. ' [[Wikipedia:Requests for page protection#' .. 'Current requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].' }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism' }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then error('no properties key') end local property = properties[propertiesKey] if not property then error('invalid properties key') end if dupes[property] then error('dupe detected') else dupes[property] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then error('invalid category order string') end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error('No category match found; please define the category for key "all-all-all-all-all"') end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p 7g4p94y2b0imjyn59e3elh58ib3vfpc 28117 28116 2014-03-19T05:06:57Z w>Mr. Stradivarius 0 make the category name function errors more descriptive 28117 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { categoryOrder = 'reason', banner = 'blp' }, dispute = { categoryOrder = 'reason', banner = 'dispute' }, office = { categoryOrder = 'reason', banner = 'office' }, sock = { categoryOrder = 'reason', banner = 'sock' }, usertalk = { banner = 'usertalk' }, vandalism = { categoryOrder = 'namespace', banner = 'vandalism' } } cfg.banners = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link blp = { }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true }, office = { }, sock = { }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection#' .. 'Current requests for edits to a protected page|request an edit]],' .. ' [[Wikipedia:Requests for page protection#' .. 'Current requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].' }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism' }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p cvtea79ix6emid256fn2riswphn54bl 28118 28117 2014-03-19T05:24:05Z w>Mr. Stradivarius 0 add some more text and tooltip values 28118 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { categoryOrder = 'reason', banner = 'blp' }, dispute = { categoryOrder = 'reason', banner = 'dispute' }, office = { categoryOrder = 'reason', banner = 'office' }, sock = { categoryOrder = 'reason', banner = 'sock' }, usertalk = { banner = 'usertalk' }, vandalism = { categoryOrder = 'namespace', banner = 'vandalism' } } cfg.banners = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link blp = { text = 'to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = 'to promote compliance with the policy on biographies of' .. ' living people' }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true }, office = { }, sock = { text = 'to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = 'to prevent sock puppets of blocked or banned users from' .. ' editing it' }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].' }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism' }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p gqrym9rrvc1dlhjym9iagl2d0qwn610 28119 28118 2014-03-20T00:17:37Z w>Mr. Stradivarius 0 add office blurb 28119 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { categoryOrder = 'reason', banner = 'blp' }, dispute = { categoryOrder = 'reason', banner = 'dispute' }, office = { categoryOrder = 'reason', banner = 'office' }, sock = { categoryOrder = 'reason', banner = 'sock' }, usertalk = { banner = 'usertalk' }, vandalism = { categoryOrder = 'namespace', banner = 'vandalism' } } cfg.banners = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." blp = { text = 'to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = 'to promote compliance with the policy on biographies of' .. ' living people' }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4' }, sock = { text = 'to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = 'to prevent sock puppets of blocked or banned users from' .. ' editing it' }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].' }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism' }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p h1cwh4iq0i8kdupxeib6wk9xac3025c 28120 28119 2014-03-20T06:38:49Z w>Mr. Stradivarius 0 add the reset banner blurb 28120 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { categoryOrder = 'reason', banner = 'blp' }, dispute = { categoryOrder = 'reason', banner = 'dispute' }, office = { categoryOrder = 'reason', banner = 'office' }, sock = { categoryOrder = 'reason', banner = 'sock' }, usertalk = { banner = 'usertalk' }, vandalism = { categoryOrder = 'namespace', banner = 'vandalism' } } cfg.banners = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." -- $5 = the protection date blp = { text = 'to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = 'to promote compliance with the policy on biographies of' .. ' living people' }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4' }, reset = { text = [=[ '''On $5 this article was reduced to a simplified, "bare bones" version so that it may be completely rewritten to ensure it meets the policies of [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]]. Standard Wikipedia policies will apply to its rewriting—which will eventually be open to all editors—and will be strictly enforced. The article has been placed under a level of semi-protection temporarily during the rebuilding of this article. Any insertion of material directly from pre-protection revisions of the article will be removed, as will any material added to the article that is not properly sourced. The associated talk page(s) were also cleared on the same date. '''Administrators may not override this action without approval from someone from the [[WP:OFFICE|Office]]. No editor may remove this notice.]=] }, sock = { text = 'to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = 'to prevent sock puppets of blocked or banned users from' .. ' editing it' }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].' }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism' }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p m9vgkr0wv5kjh27jtbt3gvnlwf4jltk 28121 28120 2014-03-20T06:49:33Z w>Mr. Stradivarius 0 format reset blurb for easier readability 28121 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { blp = { categoryOrder = 'reason', banner = 'blp' }, dispute = { categoryOrder = 'reason', banner = 'dispute' }, office = { categoryOrder = 'reason', banner = 'office' }, sock = { categoryOrder = 'reason', banner = 'sock' }, usertalk = { banner = 'usertalk' }, vandalism = { categoryOrder = 'namespace', banner = 'vandalism' } } cfg.banners = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." -- $5 = the protection date blp = { text = 'to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = 'to promote compliance with the policy on biographies of' .. ' living people' }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4' }, reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" }, sock = { text = 'to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = 'to prevent sock puppets of blocked or banned users from' .. ' editing it' }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].' }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism' }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p l8v0hecomxye8ztjx1fu5ke7dq63adt 28122 28121 2014-03-25T08:38:27Z w>Mr. Stradivarius 0 merge the reasons and banners tables 28122 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." -- $5 = the protection date blp = { text = 'to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = 'to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4', categoryOrder = 'reason', }, reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = 'to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = 'to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism', categoryOrder = 'namespace', }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p 8wj3zgg67kd6hk3w6y2vj39w4rq8zb1 28123 28122 2014-03-26T07:58:42Z w>Mr. Stradivarius 0 add a function to get the protection data, and start work on a main function 28123 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." -- $5 = the protection date blp = { text = 'to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = 'to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4', categoryOrder = 'reason', }, reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = 'to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = 'to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism', categoryOrder = 'namespace', }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel.main(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end elseif key == 'pc' then level = mProtectionLevel.pending(title) end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end return p fn6iqvhlgg10fekgfc45wzj5kv755k4 28124 28123 2014-05-26T14:35:11Z w>Mr. Stradivarius 0 add notes about when to add error/tracking categories 28124 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." -- $5 = the protection date blp = { text = 'to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = 'to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4', categoryOrder = 'reason', }, reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = 'to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = 'to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism', categoryOrder = 'namespace', }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['pc-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['pc-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel.main(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end elseif key == 'pc' then level = mProtectionLevel.pending(title) end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p a0i74p5f73rhedbhw3ni4tbzcuwr1ut 28125 28124 2014-05-27T00:32:13Z w>Jackmcbarn 0 reflect changes to [[Module:Effective protection level]] 28125 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." -- $5 = the protection date blp = { text = 'to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = 'to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4', categoryOrder = 'reason', }, reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = 'to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = 'to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = 'due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism', categoryOrder = 'namespace', }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p tg8t54ada45snd6gafn727x0luaz1xh 28126 28125 2014-05-27T05:57:34Z w>Mr. Stradivarius 0 add some more variables to the reasons text 28126 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." -- $5 = the protection date -- $6 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $7 = {{vandal-m|username}} replacement blp = { text = '$6 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$6 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$6 $1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4', categoryOrder = 'reason', }, reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$6 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$6 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$6 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$6 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = 'due to vandalism', categoryOrder = 'namespace', }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p 6t3mtrdas1lrgo26enewykf9lkzd4sx 28127 28126 2014-05-27T05:58:43Z w>Mr. Stradivarius 0 missed one 28127 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = "until" or "or until" depending on the expiry -- $2 = "disputes", with or without a section link -- $3 = the type of the page, e.g. "article", "template", or "page" -- $4 = A blurb "it has been protected for x years, x months and x days." -- $5 = the protection date -- $6 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $7 = {{vandal-m|username}} replacement blp = { text = '$6 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$6 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$6 $1 editing $2 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $3 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $4', categoryOrder = 'reason', }, reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$6 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$6 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$6 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$6 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$6 due to vandalism', categoryOrder = 'namespace', }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p n7pkb9o70w2osstbp0hocj8g9zhwatl 28128 28127 2014-05-27T07:33:51Z w>Mr. Stradivarius 0 renumber the cfg.reasons parameters 28128 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p 32646fathejjzvk1e3nwl5b95pm1fxg 28129 28128 2014-05-27T13:23:13Z w>Jackmcbarn 0 fix indentation 28129 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.reasons = { -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', }, } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p sumqt644cpwpskei25smv4b259zg7zp 28130 28129 2014-05-27T23:46:51Z w>Mr. Stradivarius 0 new structure for the banners table 28130 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } --[[ -- Not currently used local error_categories = { incorrect = 'Wikipedia pages with incorrect protection templates', no_expiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } --]] -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p 5dnuxjer4qqtp05ky1fo0uaps96u402 28131 28130 2014-05-28T01:44:20Z w>Mr. Stradivarius 0 make outline of the main function 28131 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Define often-used functions as local variables. local tconcat = table.concat local tinsert = table.insert local tremove = table.remove local ceil = math.ceil local format = string.format local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return tinsert(t, tremove(t, pos)) end local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) -- Get the protection level of the title we are working on. local protectionLevel do local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) protectionLevel = protectionData[args.action or 'edit'] protectionLevel = protectionLevel or '*' end -- Generate the banner or padlock output. local ret = '' ret = ret .. p.renderBannerOrPadlock(protectionLevel, args) -- Add protection category if protectionLevel ~= '*' then ret = ret .. p.renderProtectionCategory(protectionLevel, args) end -- Add tracking categories ret = ret .. p.renderTrackingCategories(protectionLevel, args) return ret end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = tconcat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end function p.renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function p.renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function p.renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p mzbldwjn66ogpoj0scpm4gkdnvkwzf9 28132 28131 2014-05-28T07:20:47Z w>Mr. Stradivarius 0 start converting this to an object-oriented approach - the banner seems naturally suited to object-based code 28132 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Banner object -------------------------------------------------------------------------------- local banner = {} function banner.new(args) local obj = {} setmetatable(obj, { __index = banner }) -- Set the protection action. -- This is the action we are supposed to be protecting the page against, -- and does not necessarily correspond to the actual protection status. obj.action = args.action or 'edit' -- Get the title object of the page we are working on. if args.page then obj.title = mw.title.new(args.page) else obj.title = mw.title.getCurrentTitle() end -- Get the protection level of the title object for the given protection -- action. This is always a string, even for invalid actions. do local protectionData = p.getProtectionData(obj.title) local protectionLevel = protectionData[obj.action] obj.protectionLevel = protectionLevel or '*' end -- Fetch the banner data. obj.reason = args.reason if obj.reason and cfg.banners[obj.action] and cfg.banners[obj.action][obj.reason] then obj.data = cfg.banners[obj.action][obj.reason] elseif cfg.defaultBanners and cfg.defaultBanners[obj.action] then obj.data = cfg.defaultBanners[obj.action] elseif cfg.defaultBanners and cfg.defaultBanners.edit then obj.data = cfg.defaultBanners.edit else error('no banner data found; please define data for cfg.defaultBanners.edit') end return obj end function banner:renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function banner:renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function banner:renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) -- Find what action we are supposed to be protecting the page from. -- Add the banner/padlock, protection category, and tracking categories. local ret = '' ret = ret .. p.renderBannerOrPadlock(action, protectionLevel, args) ret = ret .. p.renderProtectionCategory(action, protectionLevel, args) ret = ret .. p.renderTrackingCategories(action, protectionLevel, args) return ret end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p ijcza4udz1io1n5s3gzsno26ysq6usq 28133 28132 2014-05-28T14:30:22Z w>Mr. Stradivarius 0 add some more to the banner.new function 28133 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Banner object -------------------------------------------------------------------------------- local banner = {} function banner.new(args) local obj = {} setmetatable(obj, { __index = banner }) -- Set the protection action. -- This is the action we are supposed to be protecting the page against, -- and does not necessarily correspond to the actual protection status. obj.action = args.action or 'edit' -- Get the title object of the page we are working on. if args.page then obj.title = mw.title.new(args.page) else obj.title = mw.title.getCurrentTitle() end -- Get the protection level of the title object for the given protection -- action. This is always a string, even for invalid actions. do local protectionData = p.getProtectionData(obj.title) local protectionLevel = protectionData[obj.action] obj.protectionLevel = protectionLevel or '*' end -- Fetch the banner data and copy it into the object. -- This could be problematic if the data table and the banner object have -- any duplicate keys, so check for those. do local data if args.reason and cfg.banners[obj.action] and cfg.banners[obj.action][args.reason] then data = cfg.banners[obj.action][obj.reason] elseif cfg.defaultBanners[obj.action] then data = cfg.defaultBanners[obj.action] elseif cfg.defaultBanners.edit then data = cfg.defaultBanners.edit else error('no banner data found; please define data for cfg.defaultBanners') end local usedFields = {} for k in pairs(banner) do usedFields[k] = true end for k in pairs(obj) do usedFields[k] = true end for k, v in pairs(data) do if usedFields[k] then error('banner.new: duplicate config key "' .. tostring(k) .. '" detected') else obj[k] = v end end end return obj end function banner:renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function banner:renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function banner:renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end function banner:export() -- Add the banner/padlock, protection category, and tracking categories. local ret = '' ret = ret .. self:renderBannerOrPadlock() ret = ret .. self:renderProtectionCategory() ret = ret .. self:renderTrackingCategories() return ret end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p 801cxg2fta3nscu1wbmjnfqwq35nr35 28134 28133 2014-05-28T23:47:33Z w>Mr. Stradivarius 0 small code 28134 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Banner object -------------------------------------------------------------------------------- local banner = {} function banner.new(args) local obj = {} setmetatable(obj, { __index = banner }) -- Set the protection action. -- This is the action we are supposed to be protecting the page against, -- and does not necessarily correspond to the actual protection status. obj.action = args.action or 'edit' -- Get the title object of the page we are working on. if args.page then obj.title = mw.title.new(args.page) else obj.title = mw.title.getCurrentTitle() end -- Get the protection level of the title object for the given protection -- action. This is always a string, even for invalid actions. do local protectionData = p.getProtectionData(obj.title) local protectionLevel = protectionData[obj.action] obj.protectionLevel = protectionLevel or '*' end -- Fetch the banner data and copy it into the object. -- This could be problematic if the data table and the banner object have -- any duplicate keys, so check for those. do local data if args.reason and cfg.banners[obj.action] and cfg.banners[obj.action][args.reason] then data = cfg.banners[obj.action][obj.reason] elseif cfg.defaultBanners[obj.action] then data = cfg.defaultBanners[obj.action] elseif cfg.defaultBanners.edit then data = cfg.defaultBanners.edit else error('no banner data found; please define data for cfg.defaultBanners') end local usedFields = {} for k in pairs(banner) do usedFields[k] = true end for k in pairs(obj) do usedFields[k] = true end for k, v in pairs(data) do if usedFields[k] then error('banner.new: duplicate config key "' .. tostring(k) .. '" detected') else obj[k] = v end end end -- Find whether we are outputting a padlock or a full banner. if obj.small == nil then -- Let the config data take precedence over user-specified arguments obj.small = yesno(args.small) or false end return obj end function banner:renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function banner:renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function banner:renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end function banner:export() -- Add the banner/padlock, protection category, and tracking categories. local ret = '' ret = ret .. self:renderBannerOrPadlock() ret = ret .. self:renderProtectionCategory() ret = ret .. self:renderTrackingCategories() return ret end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p 91t9zfiuegflrf9w406xntdorkeie4h 28135 28134 2014-05-29T06:34:38Z w>Mr. Stradivarius 0 add image names 28135 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Banner object -------------------------------------------------------------------------------- local banner = {} function banner.new(args) local obj = {} setmetatable(obj, { __index = banner }) -- Set the protection action. -- This is the action we are supposed to be protecting the page against, -- and does not necessarily correspond to the actual protection status. obj.action = args.action or 'edit' -- Get the title object of the page we are working on. if args.page then obj.title = mw.title.new(args.page) else obj.title = mw.title.getCurrentTitle() end -- Get the protection level of the title object for the given protection -- action. This is always a string, even for invalid actions. do local protectionData = p.getProtectionData(obj.title) local protectionLevel = protectionData[obj.action] obj.protectionLevel = protectionLevel or '*' end -- Fetch the banner data and copy it into the object. -- This could be problematic if the data table and the banner object have -- any duplicate keys, so check for those. do local data if args.reason and cfg.banners[obj.action] and cfg.banners[obj.action][args.reason] then data = cfg.banners[obj.action][obj.reason] elseif cfg.defaultBanners[obj.action] then data = cfg.defaultBanners[obj.action] elseif cfg.defaultBanners.edit then data = cfg.defaultBanners.edit else error('no banner data found; please define data for cfg.defaultBanners') end local usedFields = {} for k in pairs(banner) do usedFields[k] = true end for k in pairs(obj) do usedFields[k] = true end for k, v in pairs(data) do if usedFields[k] then error('banner.new: duplicate config key "' .. tostring(k) .. '" detected') else obj[k] = v end end end -- Find whether we are outputting a padlock or a full banner. if obj.small == nil then -- Let the config data take precedence over user-specified arguments obj.small = yesno(args.small) or false end return obj end function banner:renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function banner:renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function banner:renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end function banner:export() -- Add the banner/padlock, protection category, and tracking categories. local ret = '' ret = ret .. self:renderBannerOrPadlock() ret = ret .. self:renderProtectionCategory() ret = ret .. self:renderTrackingCategories() return ret end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p pkfnnyar20n3qxr8n32kzn7bmx6p5ca 28136 28135 2014-05-29T07:03:37Z w>Mr. Stradivarius 0 hacky code for image rendering 28136 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } function banner:renderImage() local image if self.reason == 'office' or self.reason == 'reset' then image = cfg.images.office elseif self.title.namespace == 10 or self.title.namespace == 828 then -- We are in the template or module namespaces. if self.protectionLevel == 'templateeditor' then image = cfg.images.template elseif self.protectionLevel == 'sysop' then image = cfg.images.indef end elseif self.action == 'create' then image = cfg.images.create elseif self.action == 'move' and ( self.protectionLevel == 'templateeditor' or self.protectionLevel == 'sysop' ) then image = cfg.images.move elseif self.action == 'edit' then if self.protectionLevel == 'sysop' then image = cfg.images.full elseif self.protectionLevel == 'autoconfirmed' then image = cfg.images.semi end elseif self.action == 'autoreview' then if self.protectionLevel == 'autoconfirmed' then image = cfg.images.pc1 elseif self.protectionLevel == 'reviewer' then image = cfg.images.pc2 end else image = 'Transparent.gif' end return image end cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Banner object -------------------------------------------------------------------------------- local banner = {} function banner.new(args) local obj = {} setmetatable(obj, { __index = banner }) -- Set the protection action. -- This is the action we are supposed to be protecting the page against, -- and does not necessarily correspond to the actual protection status. obj.action = args.action or 'edit' -- Get the title object of the page we are working on. if args.page then obj.title = mw.title.new(args.page) else obj.title = mw.title.getCurrentTitle() end -- Get the protection level of the title object for the given protection -- action. This is always a string, even for invalid actions. do local protectionData = p.getProtectionData(obj.title) local protectionLevel = protectionData[obj.action] obj.protectionLevel = protectionLevel or '*' end -- Fetch the banner data and copy it into the object. -- This could be problematic if the data table and the banner object have -- any duplicate keys, so check for those. do local data if args.reason and cfg.banners[obj.action] and cfg.banners[obj.action][args.reason] then data = cfg.banners[obj.action][obj.reason] elseif cfg.defaultBanners[obj.action] then data = cfg.defaultBanners[obj.action] elseif cfg.defaultBanners.edit then data = cfg.defaultBanners.edit else error('no banner data found; please define data for cfg.defaultBanners') end local usedFields = {} for k in pairs(banner) do usedFields[k] = true end for k in pairs(obj) do usedFields[k] = true end for k, v in pairs(data) do if usedFields[k] then error('banner.new: duplicate config key "' .. tostring(k) .. '" detected') else obj[k] = v end end end -- Find whether we are outputting a padlock or a full banner. if obj.small == nil then -- Let the config data take precedence over user-specified arguments obj.small = yesno(args.small) or false end return obj end function banner:renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function banner:renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function banner:renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end function banner:export() -- Add the banner/padlock, protection category, and tracking categories. local ret = '' ret = ret .. self:renderBannerOrPadlock() ret = ret .. self:renderProtectionCategory() ret = ret .. self:renderTrackingCategories() return ret end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p 1ws051as9ohq0b8hfq2vp6fyg89lc59 28137 28136 2014-05-29T07:06:39Z w>Mr. Stradivarius 0 move the image name function to its proper place and rename it 28137 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Banner object -------------------------------------------------------------------------------- local banner = {} function banner.new(args) local obj = {} setmetatable(obj, { __index = banner }) -- Set the protection action. -- This is the action we are supposed to be protecting the page against, -- and does not necessarily correspond to the actual protection status. obj.action = args.action or 'edit' -- Get the title object of the page we are working on. if args.page then obj.title = mw.title.new(args.page) else obj.title = mw.title.getCurrentTitle() end -- Get the protection level of the title object for the given protection -- action. This is always a string, even for invalid actions. do local protectionData = p.getProtectionData(obj.title) local protectionLevel = protectionData[obj.action] obj.protectionLevel = protectionLevel or '*' end -- Fetch the banner data and copy it into the object. -- This could be problematic if the data table and the banner object have -- any duplicate keys, so check for those. do local data if args.reason and cfg.banners[obj.action] and cfg.banners[obj.action][args.reason] then data = cfg.banners[obj.action][obj.reason] elseif cfg.defaultBanners[obj.action] then data = cfg.defaultBanners[obj.action] elseif cfg.defaultBanners.edit then data = cfg.defaultBanners.edit else error('no banner data found; please define data for cfg.defaultBanners') end local usedFields = {} for k in pairs(banner) do usedFields[k] = true end for k in pairs(obj) do usedFields[k] = true end for k, v in pairs(data) do if usedFields[k] then error('banner.new: duplicate config key "' .. tostring(k) .. '" detected') else obj[k] = v end end end -- Find whether we are outputting a padlock or a full banner. if obj.small == nil then -- Let the config data take precedence over user-specified arguments obj.small = yesno(args.small) or false end return obj end function banner:fetchImageName() local image if self.reason == 'office' or self.reason == 'reset' then image = cfg.images.office elseif self.title.namespace == 10 or self.title.namespace == 828 then -- We are in the template or module namespaces. if self.protectionLevel == 'templateeditor' then image = cfg.images.template elseif self.protectionLevel == 'sysop' then image = cfg.images.indef end elseif self.action == 'create' then image = cfg.images.create elseif self.action == 'move' and ( self.protectionLevel == 'templateeditor' or self.protectionLevel == 'sysop' ) then image = cfg.images.move elseif self.action == 'edit' then if self.protectionLevel == 'sysop' then image = cfg.images.full elseif self.protectionLevel == 'autoconfirmed' then image = cfg.images.semi end elseif self.action == 'autoreview' then if self.protectionLevel == 'autoconfirmed' then image = cfg.images.pc1 elseif self.protectionLevel == 'reviewer' then image = cfg.images.pc2 end else image = 'Transparent.gif' end return image end function banner:renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function banner:renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function banner:renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end function banner:export() -- Add the banner/padlock, protection category, and tracking categories. local ret = '' ret = ret .. self:renderBannerOrPadlock() ret = ret .. self:renderProtectionCategory() ret = ret .. self:renderTrackingCategories() return ret end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p dv330bxv5926uj6t70f1mt7fyr2m6b4 28138 28137 2014-06-04T23:34:42Z w>Mr. Stradivarius 0 fix variable typo 28138 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Banner object -------------------------------------------------------------------------------- local banner = {} function banner.new(args) local obj = {} setmetatable(obj, { __index = banner }) -- Set the protection action. -- This is the action we are supposed to be protecting the page against, -- and does not necessarily correspond to the actual protection status. obj.action = args.action or 'edit' -- Get the title object of the page we are working on. if args.page then obj.title = mw.title.new(args.page) else obj.title = mw.title.getCurrentTitle() end -- Get the protection level of the title object for the given protection -- action. This is always a string, even for invalid actions. do local protectionData = p.getProtectionData(obj.title) local protectionLevel = protectionData[obj.action] obj.protectionLevel = protectionLevel or '*' end -- Fetch the banner data and copy it into the object. -- This could be problematic if the data table and the banner object have -- any duplicate keys, so check for those. do local data if args.reason and cfg.banners[obj.action] and cfg.banners[obj.action][args.reason] then data = cfg.banners[obj.action][args.reason] elseif cfg.defaultBanners[obj.action] then data = cfg.defaultBanners[obj.action] elseif cfg.defaultBanners.edit then data = cfg.defaultBanners.edit else error('no banner data found; please define data for cfg.defaultBanners') end local usedFields = {} for k in pairs(banner) do usedFields[k] = true end for k in pairs(obj) do usedFields[k] = true end for k, v in pairs(data) do if usedFields[k] then error('banner.new: duplicate config key "' .. tostring(k) .. '" detected') else obj[k] = v end end end -- Find whether we are outputting a padlock or a full banner. if obj.small == nil then -- Let the config data take precedence over user-specified arguments obj.small = yesno(args.small) or false end return obj end function banner:fetchImageName() local image if self.reason == 'office' or self.reason == 'reset' then image = cfg.images.office elseif self.title.namespace == 10 or self.title.namespace == 828 then -- We are in the template or module namespaces. if self.protectionLevel == 'templateeditor' then image = cfg.images.template elseif self.protectionLevel == 'sysop' then image = cfg.images.indef end elseif self.action == 'create' then image = cfg.images.create elseif self.action == 'move' and ( self.protectionLevel == 'templateeditor' or self.protectionLevel == 'sysop' ) then image = cfg.images.move elseif self.action == 'edit' then if self.protectionLevel == 'sysop' then image = cfg.images.full elseif self.protectionLevel == 'autoconfirmed' then image = cfg.images.semi end elseif self.action == 'autoreview' then if self.protectionLevel == 'autoconfirmed' then image = cfg.images.pc1 elseif self.protectionLevel == 'reviewer' then image = cfg.images.pc2 end else image = 'Transparent.gif' end return image end function banner:renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function banner:renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function banner:renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end function banner:export() -- Add the banner/padlock, protection category, and tracking categories. local ret = '' ret = ret .. self:renderBannerOrPadlock() ret = ret .. self:renderProtectionCategory() ret = ret .. self:renderTrackingCategories() return ret end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p ql1as4ja5nrjejm0ez4n3u2nbr68ch7 28139 28138 2014-06-05T01:08:07Z w>Mr. Stradivarius 0 Mr. Stradivarius moved page [[Module:User:Mr. Stradivarius/pp]] to [[Module:Protection banner]] without leaving a redirect: move this to its proper location 28138 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -------------------------------------------------------------------------------- -- Configuration -------------------------------------------------------------------------------- local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Banner object -------------------------------------------------------------------------------- local banner = {} function banner.new(args) local obj = {} setmetatable(obj, { __index = banner }) -- Set the protection action. -- This is the action we are supposed to be protecting the page against, -- and does not necessarily correspond to the actual protection status. obj.action = args.action or 'edit' -- Get the title object of the page we are working on. if args.page then obj.title = mw.title.new(args.page) else obj.title = mw.title.getCurrentTitle() end -- Get the protection level of the title object for the given protection -- action. This is always a string, even for invalid actions. do local protectionData = p.getProtectionData(obj.title) local protectionLevel = protectionData[obj.action] obj.protectionLevel = protectionLevel or '*' end -- Fetch the banner data and copy it into the object. -- This could be problematic if the data table and the banner object have -- any duplicate keys, so check for those. do local data if args.reason and cfg.banners[obj.action] and cfg.banners[obj.action][args.reason] then data = cfg.banners[obj.action][args.reason] elseif cfg.defaultBanners[obj.action] then data = cfg.defaultBanners[obj.action] elseif cfg.defaultBanners.edit then data = cfg.defaultBanners.edit else error('no banner data found; please define data for cfg.defaultBanners') end local usedFields = {} for k in pairs(banner) do usedFields[k] = true end for k in pairs(obj) do usedFields[k] = true end for k, v in pairs(data) do if usedFields[k] then error('banner.new: duplicate config key "' .. tostring(k) .. '" detected') else obj[k] = v end end end -- Find whether we are outputting a padlock or a full banner. if obj.small == nil then -- Let the config data take precedence over user-specified arguments obj.small = yesno(args.small) or false end return obj end function banner:fetchImageName() local image if self.reason == 'office' or self.reason == 'reset' then image = cfg.images.office elseif self.title.namespace == 10 or self.title.namespace == 828 then -- We are in the template or module namespaces. if self.protectionLevel == 'templateeditor' then image = cfg.images.template elseif self.protectionLevel == 'sysop' then image = cfg.images.indef end elseif self.action == 'create' then image = cfg.images.create elseif self.action == 'move' and ( self.protectionLevel == 'templateeditor' or self.protectionLevel == 'sysop' ) then image = cfg.images.move elseif self.action == 'edit' then if self.protectionLevel == 'sysop' then image = cfg.images.full elseif self.protectionLevel == 'autoconfirmed' then image = cfg.images.semi end elseif self.action == 'autoreview' then if self.protectionLevel == 'autoconfirmed' then image = cfg.images.pc1 elseif self.protectionLevel == 'reviewer' then image = cfg.images.pc2 end else image = 'Transparent.gif' end return image end function banner:renderImageLink(image, size, link, text, alt) --[[ -- Renders the image link wikitext All parameters are optional -- apart from the display text. -- -- @parameters: -- image - the image name -- size - the image size, as a number -- link - page linked to by the image -- text - the tooltip text -- alt - the alt text -- -- All parameters are optional apart from the text parameter. --]] image = image or 'Transparent.gif' size = size or 20 if link then link = '|link=' .. link else link = '' end text = text or error('No text parameter supplied to p.renderImageLink') if alt then alt = '|alt=' .. alt else alt = '' end return string.format('[[Image:%s|%dpx%s|%s%s]]', image, size, link, text, alt) end function banner:renderPadlock(image, right) --[[ -- Renders the html of the padlock seen in the top-right-hand corner -- of protected pages. -- -- @parameters: -- image - the image wikitext (required) -- right - the "right" css property value, as a string (optional) --]] image = image or error('No image parameter specified in p.renderPadlock') local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = right or '55px'} :wikitext(image) return tostring(root) end function banner:renderBanner(page, image, text) --[[ -- Renders the large protection banner placed at the top of articles, -- using the data provided in the data table. -- -- @parameters: -- page - demo page parameter to pass to {{mbox}} -- image - the image wikitext -- text - the text to display -- -- All parameters are optional. --]] mMessageBox = require('Module:Message box') local mbargs = { -- arguments for the message box module page = page, type = 'protection', image = image, text = text } return mMessageBox.main('mbox', mbargs) end function banner:export() -- Add the banner/padlock, protection category, and tracking categories. local ret = '' ret = ret .. self:renderBannerOrPadlock() ret = ret .. self:renderProtectionCategory() ret = ret .. self:renderTrackingCategories() return ret end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- local p = {} function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p ql1as4ja5nrjejm0ez4n3u2nbr68ch7 28140 28139 2014-06-06T15:25:31Z w>Mr. Stradivarius 0 give up on the OOP approach, lay out the main module structure in more detail, and move the config to [[Module:Protection banner/config]] 28140 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local mArguments = require('Module:Arguments') local mProtectionLevel = require('Module:Effective protection level')._main local mFileLink = require('Module:File link') local yesno = require('Module:Yesno') local mMessageBox -- only needs to be loaded if we are outputting a banner, so lazily initialise -- Load config local cfg = mw.loadData('Module:Protection banner/config') local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function validateField(tName, t, field, expectType, nilOk) local val = t[field] local valType = type(val) if not (valType == expectType or nilOk and valType == 'nil') then error(string.format( "type error in '%s' field '%s' (%s%s expected, got %s)", tName, tostring(field), expectType, nilOk and ' or nil' or '', valType ), 2) end end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Main functions -------------------------------------------------------------------------------- function p.main(frame) local args = mArguments.getArgs(frame) return p._main(args) end function p._main(args) local protectionLevel = p.getProtectionLevel(args) local isSmall = yesno(args.small) or false local bannerConfig = p.getBannerConfig(protectionLevel, args) local ret = '' if isSmall then ret = ret .. p.makePadlock(protectionLevel, args, bannerConfig) else ret = ret .. p.makeBanner(protectionLevel, args, bannerConfig) end ret = ret .. p.getProtectionCategory(protectionLevel, args) ret = ret .. p.getTrackingCategories(protectionLevel, args) return ret end -------------------------------------------------------------------------------- -- Protection functions -------------------------------------------------------------------------------- function p.getProtectionLevel(args) local title if args.page then title = mw.title.new(args.page) else title = mw.title.getCurrentTitle() end local protectionData = p.getProtectionData(title) protectionLevel = protectionData[args.action or 'edit'] return protectionLevel or '*' end function p.getProtectionData(title) -- Gets a table containing protection data for the given title. The data -- is cached using a metatable, and so can be indexed as needed without -- a performance loss. local protectionData = {} local actions = { create = true, edit = true, move = true, autoreview = true } setmetatable(protectionData, { __index = function (t, key) local level if actions[key] then level = mProtectionLevel(key, title) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end end protectionData[key] = level return level end }) return protectionData end -------------------------------------------------------------------------------- -- Banner config functions -------------------------------------------------------------------------------- function p.getBannerConfig(protectionLevel, args) end -------------------------------------------------------------------------------- -- Padlock functions -------------------------------------------------------------------------------- function p.makePadlock(protectionLevel, args, bannerConfig) local data = p.makePadlockData(protectionLevel, args, bannerConfig) return p.renderPadlock(data) end function p.makePadlockData(protectionLevel, args, bannerConfig) end function p.renderPadlock(data) data = data or {} local image = mFileLink.new(data.filename or 'Transparent.gif') :width(20) :link(data.link) :alt(data.alt) :render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = data.right or '55px'} :wikitext(image) return tostring(root) end -------------------------------------------------------------------------------- -- Banner functions -------------------------------------------------------------------------------- function p.makeBanner(protectionLevel, args, bannerConfig) local data = p.makeBannerData(protectionLevel, args, bannerConfig) return p.renderBanner(data) end function p.makeBannerData(protectionLevel, args, bannerConfig) end function p.renderBanner(data) data = data or {} local image = mFileLink.new(data.filename) :width(40) :caption(data.mouseover) :render() local mbargs = { page = data.page, type = 'protection', image = image, text = string.format( "'''%s'''%s", data.reasonText, data.explanationText and '<br />' .. data.explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Protection category functions -------------------------------------------------------------------------------- function p.getProtectionCategory(protectionLevel, args) end function p.getPagetype(ns) -- Returns a string with the page's type. Takes a namespace number as input. local pagetype = pagetypeNamespaces[ns] or pagetypeNamespaces.default if not pagetype then error('the page type could not be found; please define a name for the key "default"') end return pagetype end function p.matchNamespace(ns) -- Matches a namespace number to a string that can be passed to the -- namespace parameter of p.getCategoryName. if not ns or type(ns) ~= 'number' then return nil end local nskey = cfg.categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end return nskey end function p.getCategoryName(cats, action, level, namespace, reason, expiry) --[[ -- Gets a category name from the category table, given a combination of -- the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] cats = cats or cfg.categories --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = p.matchNamespace(namespace)}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end -------------------------------------------------------------------------------- -- Tracking category functions -------------------------------------------------------------------------------- function p.getTrackingCategories(protectionLevel, args) end --[[ When to add "Category:Wikipedia pages with incorrect protection templates": * If it uses a type which is incompatible with the actual protection level of a page, or * If an expiry date is set and is in the past When to add "Category:Wikipedia protected pages without expiry": * No expiry is set, and * Expiry can be set, and * The protection type is not "move" (could change this?), and * The reason doesn't have "indefinitely protected" categories (pp-blp, pp-semi-indef and pp-move-indef have these), and * The reason is not the generic pp-protected (could change this?) (This leaves reasons "dispute", "vandalism", "usertalk", and "sock") ]] return p jfcutaubc377k1l68lyza8e7rraeef5 28141 28140 2014-06-08T15:26:11Z w>Mr. Stradivarius 0 Yet Another Rewrite - this time using [[Module:Middleclass]] 28141 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local whitelisted = { images = true, categories = true, categoryNamespaces = true, pagetypeNamespaces = true, errorCategories = true } if whitelisted[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(bannerConfig) self._config = bannerConfig end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner._newBannerTemplate(args) -- Makes a new banner template object. This will be a new instance of -- the most suitable subclass of BannerTemplate, e.g. Banner or Padlock. if yesno(args.small) then return Padlock:new(args) else return Banner:new(args) end end function ProtectionBanner.exportToWiki(frame, titleObj) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() end return ProtectionBanner d2unnadvoys9m47221i9wss9rf8i4n5 28142 28141 2014-06-08T15:40:56Z w>Jackmcbarn 0 add no globals now, to catch any problems sooner rather than later 28142 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local whitelisted = { images = true, categories = true, categoryNamespaces = true, pagetypeNamespaces = true, errorCategories = true } if whitelisted[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(bannerConfig) self._config = bannerConfig end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner._newBannerTemplate(args) -- Makes a new banner template object. This will be a new instance of -- the most suitable subclass of BannerTemplate, e.g. Banner or Padlock. if yesno(args.small) then return Padlock:new(args) else return Banner:new(args) end end function ProtectionBanner.exportToWiki(frame, titleObj) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() end return ProtectionBanner fh7hj540q4c5zlz3h3gbauuvbi5zlm3 28143 28142 2014-06-08T16:17:37Z w>Mr. Stradivarius 0 export classes for testing purposes and a few other tweaks 28143 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(bannerConfig) self._config = bannerConfig end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() local pstatus = ProtectionStatus.new(args, title) local cfg = Config:new() -- Get the banner template object local banner do local bannerClass if yesno(args.small) then bannerClass = Padlock else bannerClass = Banner end banner = bannerClass:new() end end function ProtectionBanner._exportClasses() return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory } end return ProtectionBanner fp10r1qktkchoildbbq1c4bqlx852i0 28144 28143 2014-06-09T00:47:29Z w>Mr. Stradivarius 0 expand the Image class 28144 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry or 'indef' end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:setFilename(filename, configObj, protectionStatusObj, namespace) if filename then self._filename = filename else local images = configObj:getConfigTable('images') local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end else image = 'Transparent.gif' end self._filename = image end end function Image:export() return mFileLink.new(self._filename) :width(self._size) :alt(self._alt) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(bannerConfig) self._config = bannerConfig end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() local pstatus = ProtectionStatus.new(args, title) local cfg = Config:new() -- Get the banner template object local banner do local bannerClass if yesno(args.small) then bannerClass = Padlock else bannerClass = Banner end banner = bannerClass:new() end end function ProtectionBanner._exportClasses() return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory } end return ProtectionBanner rz3hyspcru4asyyhhu10acqpuhqmarv 28145 28144 2014-06-09T04:32:18Z w>Mr. Stradivarius 0 start converting the getCategoryName function 28145 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry or 'indef' end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:setFilename(filename, configObj, protectionStatusObj, namespace) if filename then self._filename = filename else local images = configObj:getConfigTable('images') local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end else image = 'Transparent.gif' end self._filename = image end end function Image:export() return mFileLink.new(self._filename) :width(self._size) :alt(self._alt) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(bannerConfig) self._config = bannerConfig end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName(name, configObj, protectionStatusObj, namespace) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] local cats = configObj:getConfigTable('categories') -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = expiry}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = reason}, level = {order = 4, keypos = 2, val = level}, action = {order = 5, keypos = 1, val = action} } --[[ -- Load the category order configuration for the reason specified. -- The configuration is stored in the categoryOrder field of each reason -- subtable of cfg.reasons. If the value is a table, then the order is the -- values specified in the table. If the value is a string, then the -- property corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If the value is of -- any other type then the canonical order is used. --]] local reasonTable = reason and cfg.reasons[reason] local categoryOrder = reasonTable and reasonTable.categoryOrder local categoryOrderType = type(categoryOrder) local configOrder = {} if categoryOrderType == 'table' then local dupes = {} for i = 1, 5 do local propertiesKey = categoryOrder[i] if not propertiesKey then local msg = 'no entry found for key ' .. i .. ' in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end local property = properties[propertiesKey] if not property then local msg = 'invalid value "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) end if dupes[propertiesKey] then local msg = 'duplicate values "' .. propertiesKey .. '" detected in the cfg.reasons.' .. reason .. '.categoryOrder table' error(msg) else dupes[propertiesKey] = true end configOrder[i] = property end else for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrderType == 'string' then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end toTableEnd(configOrder, property.order) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end local noActive = #active local attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return attempt end end error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() local pstatus = ProtectionStatus.new(args, title) local cfg = Config:new() -- Get the banner template object local banner do local bannerClass if yesno(args.small) then bannerClass = Padlock else bannerClass = Banner end banner = bannerClass:new() end end function ProtectionBanner._exportClasses() return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory } end return ProtectionBanner rzl1w5xvxv6m3iki4h1kp97tp9h9g0k 28146 28145 2014-06-09T06:09:52Z w>Mr. Stradivarius 0 finish converting p.getCategoryName 28146 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry or 'indef' end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:setFilename(filename, configObj, protectionStatusObj, namespace) if filename then self._filename = filename else local images = configObj:getConfigTable('images') local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end else image = 'Transparent.gif' end self._filename = image end end function Image:export() return mFileLink.new(self._filename) :width(self._size) :alt(self._alt) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(bannerConfig) self._config = bannerConfig end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() local pstatus = ProtectionStatus.new(args, title) local cfg = Config:new() -- Get the banner template object local banner do local bannerClass if yesno(args.small) then bannerClass = Padlock else bannerClass = Banner end banner = bannerClass:new() end end function ProtectionBanner._exportClasses() return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory } end return ProtectionBanner horf6f09uyg6zkqxo7wsvroruph9ct8 28147 28146 2014-06-09T06:59:10Z w>Mr. Stradivarius 0 make some image tweaks and start a function for substituting blurb parameters 28147 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry or 'indef' end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:setFilename(filename, configObj, protectionStatusObj, namespace) if filename then self._filename = filename else local images = configObj:getConfigTable('images') local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._size or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(bannerConfig) self._config = bannerConfig end function Blurb:_substituteParameters(msg, configObj) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end params[k] = param return param end }) parameterFuncs[1] = function () return 'This page is currently [[Help:Protection|protected]] from editing' end -- TODO: Write parameter functions self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() local pstatus = ProtectionStatus.new(args, title) local cfg = Config:new() -- Get the banner template object local banner do local bannerClass if yesno(args.small) then bannerClass = Padlock else bannerClass = Banner end banner = bannerClass:new() end end function ProtectionBanner._exportClasses() return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory } end return ProtectionBanner 384pdiylz7zwi5mlckoy28qvjgzor5b 28148 28147 2014-06-09T10:27:07Z w>Mr. Stradivarius 0 some more work on the Blurb class 28148 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry or 'indef' end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:setFilename(filename, configObj, protectionStatusObj, namespace) if filename then self._filename = filename else local images = configObj:getConfigTable('images') local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._size or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, namespace) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._namespace = namespace end function Blurb:_makeIntroParameter() end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') return pagetypes[self._namespace] or pagetypes.default or 'page' end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end params[k] = param return param end }) parameterFuncs[1] = function () return self:_makeIntroParameter() end -- TODO: Write parameter functions self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() local pstatus = ProtectionStatus.new(args, title) local cfg = Config:new() -- Get the banner template object local banner do local bannerClass if yesno(args.small) then bannerClass = Padlock else bannerClass = Banner end banner = bannerClass:new() end end function ProtectionBanner._exportClasses() return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory } end return ProtectionBanner 6p5q18hjzdsxlskkwtj9q0hf3foofzg 28149 28148 2014-06-09T15:24:10Z w>Mr. Stradivarius 0 use factory classes to get the banner and category classes, and add a PageData class so we don't expose all of mw.title to every class 28149 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- PageData class -------------------------------------------------------------------------------- --[[ -- This class represents a MediaWiki page, just as the mw.title object does. -- The difference is that this class is much simpler, using only the fields -- necessary for this module. This is to keep the module extensible while -- keeping the code as simple as possible, e.g. this way we do not expose -- mw.title's protectionLevels property to classes that only need to know a -- page's namespace. The "data" in PageData is so that this class can be more -- easily differentiated with mw.title. --]] local PageData = class('PageData') function PageData:initialize(titleObj) self._namespace = titleObj.namespace end function PageData:getNamespace() return self._namespace end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set reason self._reason = args.reason -- Set expiry self._expiry = args.expiry or 'indef' end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, pageDataObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._pageDataObj = pageDataObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local pageDataObj = self._pageDataObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = pageDataObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, pageDataObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._pageDataObj = pageDataObj end function Blurb:_makeIntroParameter() end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._pageDataObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end params[k] = param return param end }) parameterFuncs[1] = function () return self:_makeIntroParameter() end -- TODO: Write parameter functions self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- BannerFactory class -------------------------------------------------------------------------------- local BannerFactory = class('BannerFactory') function BannerFactory:initialize( args, configObj, protectionStatusObj, pageDataObj ) -- Set dependent objects self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._pageDataObj = pageDataObj -- Set object paradigm to use if yesno(args.small) then self._paradigm = 'padlock' else self._paradigm = 'banner' end end function BannerFactory:newBannerTemplate() end function BannerFactory:newBlurb() end function BannerFactory:newImage() local image = Image:new() if self._paradigm == 'padlock' then image:setWidth(20) else image:setWidth(40) end return image end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- CategoryFactory class -------------------------------------------------------------------------------- local CategoryFactory = class('CategoryFactory') function CategoryFactory:initialize( configObj, protectionStatusObj, pageDataObj ) -- Set dependent objects self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._pageDataObj = pageDataObj end function CategoryFactory:getCategoryObjects() local ret = {} local classes = {ProtectionCategory, ExpiryCategory, ErrorCategory} for i, aClass in ipairs(classes) do ret[#ret + 1] = aClass:new() end return ret end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local thePageData = PageData:new(title) local theProtectionStatus = ProtectionStatus.new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner do local theBannerFactory = BannerFactory:new( args, theConfig, theProtectionStatus, thePageData ) local banner = theBannerFactory:newBannerTemplate() local image = theBannerFactory:newImage() local blurb = theBannerFactory:newBlurb() --TODO: actual rendering ret[#ret + 1] = banner:export() end -- Render the categories do local theCategoryFactory = CategoryFactory:new( theConfig, theProtectionStatus, thePageData ) local categoryObjects = theCategoryFactory:getCategoryObjects() for i, obj in ipairs(categoryObjects) do ret[#ret + 1] = obj:export() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { PageData = PageData, ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, BannerFactory = BannerFactory, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, CategoryFactory = CategoryFactory } end return ProtectionBanner ql5axuytrlznbmnpg89z13oo69ldtda 28150 28149 2014-06-16T03:14:16Z w>Mr. Stradivarius 0 simplify the structure a bit and write some more parameter functions 28150 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._section = args.section end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getSection() return self._section end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end param = param or '' params[k] = param return param end }) parameterFuncs[1] = function () -- Intro blurb local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end parameterFuncs[2] = function () -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end parameterFuncs[3] = function () -- "disputes", with or without a section link local section = self._protectionStatusObj:getSection() local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = titleObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner hzsqjfjntxe1owi31sglyw9oth4cyo9 28151 28150 2014-06-16T05:17:31Z w>Mr. Stradivarius 0 move the parameter functions to the top level of the blurb class and add a new one 28151 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._section = args.section end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getSection() return self._section end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end param = param or '' params[k] = param return param end }) parameterFuncs[1] = function () return self:_makeIntroParameter() end parameterFuncs[2] = function () return self:_makeUntilParameter() end parameterFuncs[3] = function () return self:_makeDisputesParameter() end parameterFuncs[4] = function () return self:_makePagetypeParameter() end parameterFuncs[5] = function () return self:_makeProtectionDateParameter() end parameterFuncs[6] = function () return self:_makeVandalTemplateParameter() end parameterFuncs[7] = function () return self:_makeProtectionLevelParameter() end parameterFuncs[8] = function () return self:_makeExpiryParameter() end parameterFuncs[9] = function () return self:_makeDisputeLinkParameter() -- A link to the page history or the move log end parameterFuncs[10] = function () return self:_makeProtectionLogParameter() end parameterFuncs[11] = function () return self:_makeTalkLinkParameter() end parameterFuncs[12] = function () return self:_makeEditRequestParameter() end parameterFuncs[13] = function () return self:_makeRequestUnprotectionParameter() end parameterFuncs[14] = function () return self:_makeSubjectPageLinksParameter() -- Adds links to edit requests and the talk page if we are on a subject page end parameterFuncs[15] = function () return self:_makeDeletionDiscussionParameter() end parameterFuncs[16] = function () return self:_makeDeletionLogParameter() end self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._protectionStatusObj:getSection() local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 if self._protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', self._protectionDate ) if success and date then return date end end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = titleObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 7wn02kjka6wnikeibpt188iy3i0tedd 28152 28151 2014-06-16T07:40:30Z w>Mr. Stradivarius 0 add some more blurb parameter functions 28152 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._section = args.section self._protectionDate = args.date self._username = args.user end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getSection() return self._section end function ProtectionStatus:getProtectionDate() return self._protectionDate end function ProtectionStatus:getUsername() return self._username end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end param = param or '' params[k] = param return param end }) parameterFuncs[1] = function () return self:_makeIntroParameter() end parameterFuncs[2] = function () return self:_makeUntilParameter() end parameterFuncs[3] = function () return self:_makeDisputesParameter() end parameterFuncs[4] = function () return self:_makePagetypeParameter() end parameterFuncs[5] = function () return self:_makeProtectionDateParameter() end parameterFuncs[6] = function () return self:_makeVandalTemplateParameter() end parameterFuncs[7] = function () return self:_makeProtectionLevelParameter() end parameterFuncs[8] = function () return self:_makeExpiryParameter() end parameterFuncs[9] = function () -- A link to the page history or the move log return self:_makeDisputeLinkParameter() end parameterFuncs[10] = function () return self:_makeProtectionLogParameter() end parameterFuncs[11] = function () return self:_makeTalkLinkParameter() end parameterFuncs[12] = function () return self:_makeEditRequestParameter() end parameterFuncs[13] = function () return self:_makeRequestUnprotectionParameter() end parameterFuncs[14] = function () -- Adds links to edit requests and the talk page if we are on a -- subject page return self:_makeSubjectPageLinksParameter() end parameterFuncs[15] = function () return self:_makeDeletionDiscussionParameter() end parameterFuncs[16] = function () return self:_makeDeletionLogParameter() end self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._protectionStatusObj:getSection() local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._protectionStatusObj:getUsername() username = username or self._titleObj.baseText return mVandalM.luaMain{username} end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = titleObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner pp3zo1watg3fk2m629hfgdpyeawzaa0 28153 28152 2014-06-19T01:40:23Z w>Mr. Stradivarius 0 add more blurb functions 28153 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._section = args.section self._protectionDate = args.date self._username = args.user end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getSection() return self._section end function ProtectionStatus:getProtectionDate() return self._protectionDate end function ProtectionStatus:getUsername() return self._username end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end param = param or '' params[k] = param return param end }) parameterFuncs[1] = function () return self:_makeIntroParameter() end parameterFuncs[2] = function () return self:_makeUntilParameter() end parameterFuncs[3] = function () return self:_makeDisputesParameter() end parameterFuncs[4] = function () return self:_makePagetypeParameter() end parameterFuncs[5] = function () return self:_makeProtectionDateParameter() end parameterFuncs[6] = function () return self:_makeVandalTemplateParameter() end parameterFuncs[7] = function () return self:_makeProtectionLevelParameter() end parameterFuncs[8] = function () return self:_makeExpiryParameter() end parameterFuncs[9] = function () -- A link to the page history or the move log return self:_makeDisputeLinkParameter() end parameterFuncs[10] = function () return self:_makeProtectionLogParameter() end parameterFuncs[11] = function () return self:_makeTalkLinkParameter() end parameterFuncs[12] = function () return self:_makeEditRequestParameter() end parameterFuncs[13] = function () return self:_makeRequestUnprotectionParameter() end parameterFuncs[14] = function () -- Adds links to edit requests and the talk page if we are on a -- subject page return self:_makeSubjectPageLinksParameter() end parameterFuncs[15] = function () return self:_makeDeletionDiscussionParameter() end parameterFuncs[16] = function () return self:_makeDeletionLogParameter() end self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._protectionStatusObj:getSection() local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._protectionStatusObj:getUsername() username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = titleObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 5y5bmzi4ntkrqxcff56dcqgwnhdzefu 28154 28153 2014-06-19T05:58:44Z w>Mr. Stradivarius 0 add some more blurb functions - up to no. 13 now 28154 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._section = args.section self._protectionDate = args.date self._username = args.user end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getSection() return self._section end function ProtectionStatus:getProtectionDate() return self._protectionDate end function ProtectionStatus:getUsername() return self._username end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end param = param or '' params[k] = param return param end }) parameterFuncs[1] = function () return self:_makeIntroParameter() end parameterFuncs[2] = function () return self:_makeUntilParameter() end parameterFuncs[3] = function () return self:_makeDisputesParameter() end parameterFuncs[4] = function () return self:_makePagetypeParameter() end parameterFuncs[5] = function () return self:_makeProtectionDateParameter() end parameterFuncs[6] = function () return self:_makeVandalTemplateParameter() end parameterFuncs[7] = function () return self:_makeProtectionLevelParameter() end parameterFuncs[8] = function () return self:_makeExpiryParameter() end parameterFuncs[9] = function () -- A link to the page history or the move log return self:_makeDisputeLinkParameter() end parameterFuncs[10] = function () return self:_makeProtectionLogParameter() end parameterFuncs[11] = function () return self:_makeTalkLinkParameter() end parameterFuncs[12] = function () return self:_makeEditRequestParameter() end parameterFuncs[13] = function () return self:_makeRequestUnprotectionParameter() end parameterFuncs[14] = function () -- Adds links to edit requests and the talk page if we are on a -- subject page return self:_makeSubjectPageLinksParameter() end parameterFuncs[15] = function () return self:_makeDeletionDiscussionParameter() end parameterFuncs[16] = function () return self:_makeDeletionLogParameter() end self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._protectionStatusObj:getSection() local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._protectionStatusObj:getUsername() username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._protectionStatusObj:getSection() local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = titleObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner t09vgntrw9ktu11q3xgokitbcgby5pq 28155 28154 2014-06-19T06:35:18Z w>Mr. Stradivarius 0 finish making blurb parameter functions 28155 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._section = args.section self._protectionDate = args.date self._username = args.user self._deletionDiscussionPage = args.xfd end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getSection() return self._section end function ProtectionStatus:getProtectionDate() return self._protectionDate end function ProtectionStatus:getUsername() return self._username end function ProtectionStatus:getDeletionDiscussionPage() return self._deletionDiscussionPage end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k]() end param = param or '' params[k] = param return param end }) parameterFuncs[1] = function () return self:_makeIntroParameter() end parameterFuncs[2] = function () return self:_makeUntilParameter() end parameterFuncs[3] = function () return self:_makeDisputesParameter() end parameterFuncs[4] = function () return self:_makePagetypeParameter() end parameterFuncs[5] = function () return self:_makeProtectionDateParameter() end parameterFuncs[6] = function () return self:_makeVandalTemplateParameter() end parameterFuncs[7] = function () return self:_makeProtectionLevelParameter() end parameterFuncs[8] = function () return self:_makeExpiryParameter() end parameterFuncs[9] = function () -- A link to the page history or the move log return self:_makeDisputeLinkParameter() end parameterFuncs[10] = function () return self:_makeProtectionLogParameter() end parameterFuncs[11] = function () return self:_makeTalkLinkParameter() end parameterFuncs[12] = function () return self:_makeEditRequestParameter() end parameterFuncs[13] = function () return self:_makeRequestUnprotectionParameter() end parameterFuncs[14] = function () -- Adds links to edit requests and the talk page if we are on a -- subject page return self:_makeSubjectPageLinksParameter() end parameterFuncs[15] = function () return self:_makeDeletionBlurbParameter() end parameterFuncs[16] = function () return self:_makeDeletionDiscussionLinkParameter() end parameterFuncs[17] = function () return self:_makeDeletionLogParameter() end self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._protectionStatusObj:getSection() local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._protectionStatusObj:getUsername() username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._protectionStatusObj:getSection() local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = getDeletionDiscussionPage() local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = getDeletionDiscussionPage() if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = titleObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 8ounkfueuvl8l6hp1nv2xmql2s9k08t 28156 28155 2014-06-19T15:53:41Z w>Jackmcbarn 0 get rid of unnecessary wrapper functions 28156 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._section = args.section self._protectionDate = args.date self._username = args.user self._deletionDiscussionPage = args.xfd end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getSection() return self._section end function ProtectionStatus:getProtectionDate() return self._protectionDate end function ProtectionStatus:getUsername() return self._username end function ProtectionStatus:getDeletionDiscussionPage() return self._deletionDiscussionPage end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._protectionStatusObj:getSection() local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._protectionStatusObj:getUsername() username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._protectionStatusObj:getSection() local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = getDeletionDiscussionPage() local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = getDeletionDiscussionPage() if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = titleObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner p6i7zm4h3rkkynsv8ykgutx5e1v42jt 28157 28156 2014-06-20T00:46:46Z w>Mr. Stradivarius 0 move section, username and deletion discussion methods out of the ProtectionStatus class, as they don't really have anything to do with protection status 28157 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._protectionDate = args.date end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end -------------------------------------------------------------------------------- -- Image class -------------------------------------------------------------------------------- local Image = class('Image') function Image:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Image:setFilename(filename) if filename then self._filename = filename else local images, action, level, reason, namespace do local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj images = configObj:getConfigTable('images') action = protectionStatusObj:getAction() level = protectionStatusObj:getLevel() reason = protectionStatusObj:getReason() namespace = titleObj:getNamespace() end local image if reason == 'office' or reason == 'reset' then image = images.office elseif namespace == 10 or namespace == 828 then -- We are in the template or module namespaces. if level == 'templateeditor' then image = images.template elseif level == 'sysop' then image = images.indef end elseif action == 'create' then image = images.create elseif action == 'move' and ( level == 'templateeditor' or level == 'sysop' ) then image = images.move elseif action == 'edit' then if level == 'sysop' then image = images.full elseif level == 'autoconfirmed' then image = images.semi end elseif action == 'autoreview' then if level == 'autoconfirmed' then image = images.pc1 elseif level == 'reviewer' then image = images.pc2 end end self._filename = image end end function Image:setWidth(width) self._width = width end function Image:setAlt(alt) self._alt = alt end function Image:setLink(link) self._link = link end function Image:setCaption(caption) self._caption = caption end function Image:export() return mFileLink.new(self._filename or 'Transparent.gif') :width(self._width or 20) :alt(self._alt) :link(self._link) :caption(self._caption) :render() end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize() end function BannerTemplate:render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:export() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner k042op0qdpn26nn0w16260l2zbybywm 28158 28157 2014-06-20T07:02:09Z w>Mr. Stradivarius 0 move image code to the BannerTemplate class, and simplify it 28158 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._protectionDate = args.date end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Image = Image, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 8bzqzi9wn0sligjtb8fymwb2km56vd3 28159 28158 2014-06-21T01:50:33Z w>Mr. Stradivarius 0 remove the Image class from _exportClasses 28159 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._protectionDate = args.date end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() self._cfg = mw.loadData('Module:Protection banner/config') end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._cfg.msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter self._params = params end return mw.message.newRawMessage(msg):params(self._params):plain() end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('pagetypeNamespaces') local namespace = self._titleObj:getNamespace() return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner nxmm6npm0sokl2dpavd0qthgd22qafd 28160 28159 2014-06-21T03:22:18Z w>Mr. Stradivarius 0 use gsub instead of the mw.message library for substituting parameters, as mw.message:params doesn't work with metatables; also, a few bug fixes 28160 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._protectionDate = args.date end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() local data = mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if cfg.banners[action][reason] then return cfg.banners[action][reason] else return cfg.defaultBanners[action] end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner e80o8ygdwkncmdiwi13qaa9omymzeuw 28161 28160 2014-06-22T15:22:39Z w>Mr. Stradivarius 0 allow individual banner config items to fall back to the same value in the defaults table, and add functions for making the blurb values 28161 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mArguments = require('Module:Arguments') local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._protectionDate = args.date end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() local data = mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} configTables[#configTables + 1] = cfg.banners[action][reason] configTables[#configTables + 1] = cfg.defaultBanners[action] for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner j6jugf7hxutvbst89wtigepie3s9f4o 28162 28161 2014-06-22T23:32:13Z w>Mr. Stradivarius 0 lazily initialise modules we don't always need 28162 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules we don't always need. local mArguments, mMessageBox -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._protectionDate = args.date end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() local data = mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} configTables[#configTables + 1] = cfg.banners[action][reason] configTables[#configTables + 1] = cfg.defaultBanners[action] for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner qjobdnfulhormr9ywo95dxjpbr6ve6i 28163 28162 2014-06-23T06:05:38Z w>Mr. Stradivarius 0 add a blurb parameter function for making the explanation text 28163 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules we don't always need. local mArguments, mMessageBox -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._protectionDate = args.date end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() local data = mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) local cfg = self._cfg local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} configTables[#configTables + 1] = cfg.banners[action][reason] configTables[#configTables + 1] = cfg.defaultBanners[action] for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner qjqas4w5l5zh9lfxpbqn9v6hu1001qo 28164 28163 2014-06-23T06:53:18Z w>Mr. Stradivarius 0 allow specifying banner config by protection level as well as by action 28164 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules we don't always need. local mArguments, mMessageBox -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Set other params self._reason = args.reason self._expiry = args.expiry or 'indef' self._protectionDate = args.date end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() local data = mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then local lang = mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', protectionDate ) if success and date then return date end end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theProtectionStatus = ProtectionStatus:new(args, title) local theConfig = Config:new() local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner auzzjxtr9wltpsp3w8xyoehe9xdhgdc 28165 28164 2014-06-23T11:12:03Z w>Mr. Stradivarius 0 validate expiry and protection dates 28165 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() local data = mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set other params self._reason = args.reason self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then local date = os.date('%e %B %Y', protectionDate) date = date:gsub('^ ', '') -- The %e option replaces leading zeroes with spaces, but we don't want spaces. return date else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry then return ' until ' .. expiry else return '' end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theConfig = Config:new() local theProtectionStatus = ProtectionStatus:new(args, theConfig, title) local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner j6iaqd61w960s1brzxvoxy08oweehnd 28166 28165 2014-06-23T11:21:30Z w>Mr. Stradivarius 0 format date output in the Blurb class 28166 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() local data = mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set other params self._reason = args.reason self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. local date = os.date('%e %B %Y', num) -- The %e option replaces leading zeroes with spaces, but we don't want -- spaces. date = date:gsub('^ ', '') return date end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theConfig = Config:new() local theProtectionStatus = ProtectionStatus:new(args, theConfig, title) local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner tna7svny6zmr2xmd2s7no9anim94wmk 28167 28166 2014-06-23T11:55:26Z w>Mr. Stradivarius 0 use lang:formatDate instead of os.date as it is easier to localise 28167 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize() local data = mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set other params self._reason = args.reason self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theConfig = Config:new() local theProtectionStatus = ProtectionStatus:new(args, theConfig, title) local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner tkkkpcapuam1ky48eicfrj7a96u7vyw 28168 28167 2014-06-23T11:56:10Z w>Mr. Stradivarius 0 allow specifying a data table to config objects for testing purposes 28168 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set other params self._reason = args.reason self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._config:getMessage('semi-subject-page-links') return self._substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageAlt(alt) self._imageAlt = alt end function BannerTemplate:setImageLink(link) self._imageLink = link end function BannerTemplate:setImageCaption(caption) self._imageCaption = caption end function BannerTemplate:renderImage() local filename = self._filename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize() self:setImageWidth(40) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize() self:setImageWidth(20) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, title) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, title) end function ProtectionBanner.exportToLua(args, title) title = title or mw.title.getCurrentTitle() -- Get data objects local theConfig = Config:new() local theProtectionStatus = ProtectionStatus:new(args, theConfig, title) local ret = {} -- Render the banner local theBanner if yesno(args.small) then theBanner = Padlock.new(theConfig, theProtectionStatus, title) else theBanner = Banner.new(theConfig, theProtectionStatus, title) end theBanner = Padlock.new(theConfig, theProtectionStatus, title) theBanner:setDeletionDiscussionPage(args.xfd) theBanner:setUsername(args.user) theBanner:setSection(args.section) ret[#ret + 1] = theBanner:render() -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner cg38kgafyzc2hbewpx5o2gvjg3gt040 28169 28168 2014-06-23T14:06:46Z w>Mr. Stradivarius 0 Add render methods to the Padlock and Banner classes, and call them from the exportToLua function. Now we have something to look at, yay! 28169 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args.reason then self._reason = args.reason:lower() end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._configObj:getMessage('semi-subject-page-links') return self:_substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize() end function Category:setName(name) self._name = name end function Category:export() if self._categoryName then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._categoryName ) else return '' end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:setName( name, configObj, protectionStatusObj, namespace ) --[[ -- Sets the protection category. If a category name is not provided, this -- method gets a category name from the module config, given a combination -- of the protection type, the protection level, the namespace number, the -- reason for protection, and the expiry date. --]] -- If a name was provided, use that. if name then Category.setName(self, name) end -- Get the namespace category key from the namespace number. local nskey do local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') if not namespace or type(namespace) ~= 'number' then nskey = nil else nskey = categoryNamespaces[ns] if not nskey and ns % 2 == 1 then nskey = 'talk' end end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner nxybhfjx1c9qh0p9c69lcmwlv5trw49 28170 28169 2014-06-24T02:47:30Z w>Mr. Stradivarius 0 various category updates 28170 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args.reason then self._reason = args.reason:lower() end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._configObj:getMessage('semi-subject-page-links') return self:_substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the namespace category key from the namespace number. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if type(expiry) == 'number' and expiry < os.time() or level == '*' or action == 'move' and level == 'autoconfirmed' then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 6d6r5s4atpfkrf6dllr6rd0l0yj5ppo 28171 28170 2014-06-24T10:16:17Z w>Mr. Stradivarius 0 allow the first positional parameter to be used for the reason 28171 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._configObj:getMessage('semi-subject-page-links') return self:_substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the namespace category key from the namespace number. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, keypos = 5, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, keypos = 3, val = nskey}, reason = {order = 3, keypos = 4, val = protectionStatusObj:getReason()}, level = {order = 4, keypos = 2, val = protectionStatusObj:getLevel()}, action = {order = 5, keypos = 1, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if type(expiry) == 'number' and expiry < os.time() or level == '*' or action == 'move' and level == 'autoconfirmed' then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner qhayuilcbrvg7qzmlqftptykodkvd1f 28172 28171 2014-06-24T13:33:27Z w>Mr. Stradivarius 0 start changing the protection category function after a restructure of the config 28172 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._configObj:getMessage('semi-subject-page-links') return self:_substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the namespace category key from the namespace number. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = protectionStatusObj:getReason()}, level = {order = 4, val = protectionStatusObj:getLevel()}, action = {order = 5, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if level == '*' or action == 'move' and level == 'autoconfirmed' or type(expiry) == 'number' and expiry < os.time() then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner hjx298d90r54xardkcu5xspoj8m3nap 28173 28172 2014-06-25T06:58:34Z w>Mr. Stradivarius 0 treat semi-move-protected pages as unprotected 28173 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._configObj:getMessage('semi-subject-page-links') return self:_substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the namespace category key from the namespace number. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = protectionStatusObj:getReason()}, level = {order = 4, val = protectionStatusObj:getLevel()}, action = {order = 5, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if level == '*' or action == 'move' and level == 'autoconfirmed' or type(expiry) == 'number' and expiry < os.time() then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner r8bkwwk7sp80gj8wyyx6mpdr96e8xjw 28174 28173 2014-06-25T23:28:55Z w>Jackmcbarn 0 check the right action variable 28174 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image', 'categoryOrder', 'categoryReason' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd M, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs[1] = self._makeIntroParameter parameterFuncs[2] = self._makeUntilParameter parameterFuncs[3] = self._makeDisputesParameter parameterFuncs[4] = self._makePagetypeParameter parameterFuncs[5] = self._makeProtectionDateParameter parameterFuncs[6] = self._makeVandalTemplateParameter parameterFuncs[7] = self._makeProtectionLevelParameter parameterFuncs[8] = self._makeExpiryParameter parameterFuncs[9] = self._makeDisputeLinkParameter -- A link to the page history or the move log parameterFuncs[10] = self._makeProtectionLogParameter parameterFuncs[11] = self._makeTalkLinkParameter parameterFuncs[12] = self._makeEditRequestParameter parameterFuncs[13] = self._makeRequestUnprotectionParameter parameterFuncs[14] = self._makeSubjectPageLinksParameter -- Adds links to edit requests and the talk page if we are on a subject page parameterFuncs[15] = self._makeDeletionBlurbParameter parameterFuncs[16] = self._makeDeletionDiscussionLinkParameter parameterFuncs[17] = self._makeDeletionLogParameter parameterFuncs[18] = self._makeExplanationTextParameter self._params = params end local function getParameter(match) match = tonumber(match) return self._params[match] end msg = msg:gsub('$([1-9][0-9]*)', getParameter) return msg end function Blurb:_makeIntroParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeUntilParameter() -- parameter $2 -- "until" or "or until" depending on the expiry local expiry = self._protectionStatusObj:getExpiry() if expiry then return 'or until' else return 'until' end end function Blurb:_makeDisputesParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeDisputeLinkParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkLinkParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._configObj:getMessage('semi-subject-page-links') return self:_substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationTextParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the namespace category key from the namespace number. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = protectionStatusObj:getReason()}, level = {order = 4, val = protectionStatusObj:getLevel()}, action = {order = 5, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if level == '*' or action == 'move' and level == 'autoconfirmed' or type(expiry) == 'number' and expiry < os.time() then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 6bjg7grlffaxwwhe3i3gpphgruegmrl 28175 28174 2014-06-26T05:33:39Z w>Mr. Stradivarius 0 start converting the blurb class to the new parameter system 28175 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTESECTION = self._makeDisputesParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeIntroBlurbParameter() -- parameter $1 local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeDisputeSectionParameter() -- parameter $3 -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makePagetypeParameter() -- parameter $4 local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() -- parameter $5 local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeVandalTemplateParameter() -- parameter $6 local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end function Blurb:_makeProtectionLevelParameter() -- parameter $7 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeExpiryParameter() -- parameter $8 -- @TODO: Check to see if the expiry is valid. local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeCurrentVersionParameter() -- parameter $9 -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeProtectionLogParameter() -- parameter $10 local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkPageParameter() -- parameter $11 local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeEditRequestParameter() -- parameter $12 local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeRequestUnprotectionParameter() -- parameter $13 if self._titleObj.namespace ~= 8 then -- MediaWiki pages can't be unprotected. return self._configObj:getMessage('request-unprotection-blurb') end end function Blurb:_makeSubjectPageLinksParameter() -- parameter $14 -- Don't display these links if we are on a talk page. if not self._titleObj.isTalkPage then local msg = self._configObj:getMessage('semi-subject-page-links') return self:_substituteParameters(msg) end end function Blurb:_makeDeletionBlurbParameter() -- parameter $15 local deletionDiscussionPage = self._deletionDiscussionPage local key if deletionDiscussionPage then key = 'deletion-discussion-blurb-xfd' else key = 'deletion-discussion-blurb-noxfd' end local msg = self._configObj:getMessage(msg) return self._substituteParameters(msg) end function Blurb:_makeDeletionDiscussionLinkParameter() -- parameter $16 local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDeletionLogParameter() -- parameter $17 return Blurb.makeFullUrl( 'Special:Log', {type = 'delete', page = self._titleObj.prefixedText}, self._configObj:getMessage('deletion-log-link-display') ) end function Blurb:_makeExplanationBlurbParameter() -- parameter $18 local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the namespace category key from the namespace number. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = protectionStatusObj:getReason()}, level = {order = 4, val = protectionStatusObj:getLevel()}, action = {order = 5, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if level == '*' or action == 'move' and level == 'autoconfirmed' or type(expiry) == 'number' and expiry < os.time() then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner m42txvdcw0obxhym0ncgsfl3ebfdg9g 28176 28175 2014-06-26T13:18:42Z w>Mr. Stradivarius 0 sort parameter methods into alphabetical order, and remove the ones that are no longer needed 28176 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self._configObj:getMessage('dispute-move-link-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self._configObj:getMessage('dispute-edit-link-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self._configObj:getMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self.configObj:getMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self._configObj:getMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then local formatted = Blurb.formatDate(expiry) return ' until ' .. formatted elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' and level == 'autoconfirmed' then key = 'explanation-text-semi' elseif action == 'move' then key = 'explanation-text-move' elseif action == 'create' then key = 'explanation-text-create' else key = 'explanation-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local key local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() if action == 'edit' and level == 'autoconfirmed' then key = 'reason-text-semi' elseif action == 'move' then key = 'reason-text-move' elseif action == 'create' then key = 'reason-text-create' else key = 'reason-text-default' end local msg = self._configObj:getMessage(key) return self:_substituteParameters(msg) end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('bannerPagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or 'page' end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local key if action == 'edit' then if level == 'sysop' then key = 'protection-level-full' elseif level == 'templateeditor' then key = 'protection-level-template' elseif level == 'autoconfirmed' then key = 'protection-level-semi' end elseif action == 'move' then key = 'protection-level-move' elseif action == 'create' then key = 'protection-level-create' else key = 'protection-level-default' end return self._configObj:getMessage(key) end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self._configObj:getMessage('more-details-pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self._configObj:getMessage('more-details-protection-log-display') ) end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self._configObj:getMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM.luaMain{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the namespace category key from the namespace number. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaces') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = protectionStatusObj:getExpiry()}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = protectionStatusObj:getReason()}, level = {order = 4, val = protectionStatusObj:getLevel()}, action = {order = 5, val = protectionStatusObj:getAction()} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local bannerConfig = configObj:getBannerConfig(protectionStatusObj) local categoryOrder = bannerConfig.categoryOrder for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if categoryOrder then local property = properties[categoryOrder] if not property then local msg = '"' .. categoryOrder .. '" is not a valid value of cfg.reasons.' .. reason .. '.categoryOrder' error(msg) end table.insert(configOrder, table.remove(configOrder, property.order)) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('categories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if level == '*' or action == 'move' and level == 'autoconfirmed' or type(expiry) == 'number' and expiry < os.time() then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner t0o0sicm0yr3pb2kjdozsohyu9y4rqr 28177 28176 2014-06-26T15:05:17Z w>Mr. Stradivarius 0 add missing parameter methods, add a Blurb:_getExpandedMessage method, and (hopefully) finish updating the various functions to work with the new config structure 28177 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the expiry. local expiry = protectionStatusObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionStatusObj:getReason() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if level == '*' or action == 'move' and level == 'autoconfirmed' or type(expiry) == 'number' and expiry < os.time() then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner owbilh6xujyb33egr2g3cgttdvgv0dl 28178 28177 2014-06-26T23:46:33Z w>Mr. Stradivarius 0 add expiry category code 28178 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._titleObj = titleObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the expiry. local expiry = protectionStatusObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionStatusObj:getReason() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.export(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then local cat = configObj:getMessage('tracking-category-expiry') Category.setName(self, cat) return Category.export(self) end end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if level == '*' or type(expiry) == 'number' and expiry < os.time() then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.export(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner do -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner t5fs85g5cbjw3a7gpcftz28k5r4x97n 28179 28178 2014-06-27T01:26:28Z w>Mr. Stradivarius 0 output the categories, and don't display the banner if the page is not protected 28179 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. local level = protectionStatusObj:getLevel() if level == '*' then return '' end -- Get the expiry. local expiry = protectionStatusObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionStatusObj:getReason() local action = protectionStatusObj:getAction() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then Category.setName(self, cat) return Category.render(self) else error( 'No category match found;' .. ' please define the category for key "all-all-all-all-all"' ) end end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then local cat = configObj:getMessage('tracking-category-expiry') Category.setName(self, cat) return Category.render(self) end end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if level == '*' or type(expiry) == 'number' and expiry < os.time() then Category.setName(self, configObj:getMessage('tracking-category-incorrect')) return Category.render(self) end end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:getLevel() ~= '*' then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories do local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner ap8wh3p9rm6ubb4lr4f8384go7ji3al 28180 28179 2014-06-27T01:49:25Z w>Mr. Stradivarius 0 add template protection tracking category 28180 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:isProtected() return self._level ~= '*' end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionStatusObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionStatusObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionStatusObj:getReason() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if not protectionStatusObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( action == 'create' or not (namespace == 10 or namespace == 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:getLevel() ~= '*' then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories do local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 3rvdp9xv38ltk7igwspsdbkxnb75twj 28181 28180 2014-06-27T01:59:31Z w>Jackmcbarn 0 check against edit/move, rather than for create, and simplify logic 28181 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:isProtected() return self._level ~= '*' end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionStatusObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionStatusObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionStatusObj:getReason() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if not protectionStatusObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:getLevel() ~= '*' then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories do local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 3sopzdwukuid4fxz5gtr1guplb81asi 28182 28181 2014-06-27T03:41:28Z w>Mr. Stradivarius 0 allow category suppression with category=no 28182 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:isProtected() return self._level ~= '*' end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, action, level, namespace, expiry) if filename then self._imageFilename = filename return nil end if not action or not level then -- If the filename is not specified, we need the action and the level -- to find the image name. The namespace and the expiry are optional, -- however. return nil end -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionStatusObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionStatusObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionStatusObj:getReason() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if not protectionStatusObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:getLevel() ~= '*' then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) local imageFilename = bannerConfig.image bannerObj:setImageFilename( imageFilename, protectionObj:getAction(), protectionObj:getLevel(), titleObj.namespace, protectionObj:getExpiry() ) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 5ufcylve0dhatwiw69jv4vphzg44i1r 28183 28182 2014-06-27T05:00:33Z w>Mr. Stradivarius 0 change BannerTemplate:setImageFilename to accept protection objects and title objects rather than individual parameters 28183 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionStatusObj) if self._bannerConfigTables[protectionStatusObj] then return self._bannerConfigTables[protectionStatusObj] else local ret = {} local cfg = self._cfg local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local reason = protectionStatusObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionStatusObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- ProtectionStatus class -------------------------------------------------------------------------------- local ProtectionStatus = class('ProtectionStatus') function ProtectionStatus:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function ProtectionStatus:getAction() return self._action end function ProtectionStatus:getLevel() return self._level end function ProtectionStatus:isProtected() return self._level ~= '*' end function ProtectionStatus:getReason() return self._reason end function ProtectionStatus:getExpiry() return self._expiry end function ProtectionStatus:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionStatusObj, titleObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj self._bannerConfig = configObj:getBannerConfig(protectionStatusObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionStatusObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionStatusObj:getAction() local level = self._protectionStatusObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionStatusObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionStatusObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionStatusObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionStatusObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionStatusObj:getAction() local level = protectionStatusObj:getAction() local expiry = protectionStatusObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionStatusObj) self._configObj = configObj self._protectionStatusObj = protectionStatusObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionStatusObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionStatusObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionStatusObj:getReason() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local reason = protectionStatusObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local expiry = protectionStatusObj:getExpiry() local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() if not protectionStatusObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionStatusObj, titleObj) Category.initialize(self, configObj, protectionStatusObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionStatusObj = self._protectionStatusObj local titleObj = self._titleObj local action = protectionStatusObj:getAction() local level = protectionStatusObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = ProtectionStatus:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:getLevel() ~= '*' then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { ProtectionStatus = ProtectionStatus, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner ni1yb99t0vbxw2w22o68akd0zyjfktm 28184 28183 2014-06-27T05:07:15Z w>Mr. Stradivarius 0 shorter names - use protectionObj instead of protectionStatusObj, and Protection instead of ProtectionStatus 28184 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionObj) if self._bannerConfigTables[protectionObj] then return self._bannerConfigTables[protectionObj] else local ret = {} local cfg = self._cfg local action = protectionObj:getAction() local level = protectionObj:getLevel() local reason = protectionObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function Protection:getAction() return self._action end function Protection:getLevel() return self._level end function Protection:isProtected() return self._level ~= '*' end function Protection:getReason() return self._reason end function Protection:getExpiry() return self._expiry end function Protection:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = configObj:getBannerConfig(protectionObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj:getAction() local level = protectionObj:getAction() local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj:getAction() local level = protectionObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local level = protectionObj:getLevel() if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj:getAction() local level = protectionObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:getLevel() ~= '*' then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner qf23edfy0vd02k8ve0a0skiocwsirwz 28185 28184 2014-06-27T05:23:39Z w>Mr. Stradivarius 0 only make link text if the link message is available 28185 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionObj) if self._bannerConfigTables[protectionObj] then return self._bannerConfigTables[protectionObj] else local ret = {} local cfg = self._cfg local action = protectionObj:getAction() local level = protectionObj:getLevel() local reason = protectionObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function Protection:getAction() return self._action end function Protection:getLevel() return self._level end function Protection:isProtected() return self._level ~= '*' end function Protection:getReason() return self._reason end function Protection:getExpiry() return self._expiry end function Protection:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = configObj:getBannerConfig(protectionObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text return self:_substituteParameters(msg) end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link if msg then return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj:getAction() local level = protectionObj:getAction() local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj:getAction() local level = protectionObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local level = protectionObj:getLevel() if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj:getAction() local level = protectionObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:getLevel() ~= '*' then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner rr6qelw5std9kdnxeayclswpzrxejn7 28186 28185 2014-06-27T05:38:54Z w>Mr. Stradivarius 0 add an image link parameter, and get the link data from the banner config 28186 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionObj) if self._bannerConfigTables[protectionObj] then return self._bannerConfigTables[protectionObj] else local ret = {} local cfg = self._cfg local action = protectionObj:getAction() local level = protectionObj:getLevel() local reason = protectionObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function Protection:getAction() return self._action end function Protection:getLevel() return self._level end function Protection:isProtected() return self._level ~= '*' end function Protection:getReason() return self._reason end function Protection:getExpiry() return self._expiry end function Protection:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = configObj:getBannerConfig(protectionObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj:getConfigTable('imageLinks') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj:getAction() local level = protectionObj:getAction() local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj:getAction() local level = protectionObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local level = protectionObj:getLevel() if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj:getAction() local level = protectionObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:getLevel() ~= '*' then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner qtshdepv9427a44ub9ey2y9wdq8qgsb 28187 28186 2014-06-27T05:46:46Z w>Mr. Stradivarius 0 use Protection:isProtected instead of checking using getLevel 28187 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionObj) if self._bannerConfigTables[protectionObj] then return self._bannerConfigTables[protectionObj] else local ret = {} local cfg = self._cfg local action = protectionObj:getAction() local level = protectionObj:getLevel() local reason = protectionObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function Protection:getAction() return self._action end function Protection:getLevel() return self._level end function Protection:isProtected() return self._level ~= '*' end function Protection:getReason() return self._reason end function Protection:getExpiry() return self._expiry end function Protection:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = configObj:getBannerConfig(protectionObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj:getConfigTable('imageLinks') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj:getAction() local level = protectionObj:getAction() local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj:getAction() local level = protectionObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local level = protectionObj:getLevel() if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj:getAction() local level = protectionObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner j93s6bcvy13nxyb93nahnzq3x5dpwf1 28188 28187 2014-06-27T05:54:14Z w>Mr. Stradivarius 0 fix method name 28188 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local mFileLink = require('Module:File link') local mProtectionLevel = require('Module:Effective protection level') local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionObj) if self._bannerConfigTables[protectionObj] then return self._bannerConfigTables[protectionObj] else local ret = {} local cfg = self._cfg local action = protectionObj:getAction() local level = protectionObj:getLevel() local reason = protectionObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = mProtectionLevel._main(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function Protection:getAction() return self._action end function Protection:getLevel() return self._level end function Protection:isProtected() return self._level ~= '*' end function Protection:getReason() return self._reason end function Protection:getExpiry() return self._expiry end function Protection:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = configObj:getBannerConfig(protectionObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj:getConfigTable('imageLinks') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj:getAction() local level = protectionObj:getLevel() local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return mFileLink.new(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj:getAction() local level = protectionObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local level = protectionObj:getLevel() if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj:getAction() local level = protectionObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 91kw8hyrpiz1hcfu8rdmrlpxtmb4905 28189 28188 2014-06-27T17:05:18Z w>Jackmcbarn 0 don't keep the whole export table around when we only need one thing from it 28189 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionObj) if self._bannerConfigTables[protectionObj] then return self._bannerConfigTables[protectionObj] else local ret = {} local cfg = self._cfg local action = protectionObj:getAction() local level = protectionObj:getLevel() local reason = protectionObj:getReason() local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') end function Protection:getAction() return self._action end function Protection:getLevel() return self._level end function Protection:isProtected() return self._level ~= '*' end function Protection:getReason() return self._reason end function Protection:getExpiry() return self._expiry end function Protection:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = configObj:getBannerConfig(protectionObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj:getConfigTable('imageLinks') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj:getAction() local level = protectionObj:getLevel() local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj:getAction() local level = protectionObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = configObj:getConfigTable('expiryCheckActions') local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local level = protectionObj:getLevel() if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj:getAction() local level = protectionObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 95e23f1pluwl4ep7y3eikumkn8k8pb1 28190 28189 2014-06-28T01:46:19Z w>Jackmcbarn 0 get rid of the config class while still allowing replacing it for testing 28190 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang, config -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self._action = args.action else self._action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self._action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self._action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self._action] then configTables[#configTables + 1] = cfg.banners[self._action][self._reason] end if cfg.defaultBanners[self._action] then configTables[#configTables + 1] = cfg.defaultBanners[self._action][self._level] configTables[#configTables + 1] = cfg.defaultBanners[self._action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:getAction() return self._action end function Protection:getLevel() return self._level end function Protection:isProtected() return self._level ~= '*' end function Protection:getReason() return self._reason end function Protection:getExpiry() return self._expiry end function Protection:getProtectionDate() return self._protectionDate end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj:getAction() local level = self._protectionObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj:getAction() local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj:getAction() local level = protectionObj:getLevel() local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj:getAction() local level = protectionObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = configObj.cfg.expiryCheckActions local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj.msg['tracking-category-expiry']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj:getAction() local level = protectionObj:getLevel() if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj.msg['tracking-category-incorrect']) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj:getAction() local level = protectionObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj.msg['tracking-category-template']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects if not config then config = mw.loadData('Module:Protection banner/config') end local configObj = config local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner iaoffu9xyraahey0dqy2g1q8w54izr9 28191 28190 2014-06-28T01:47:20Z w>Mr. Stradivarius 0 (edit conflict) replace Protection getter functions with public attributes 28191 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Config class -------------------------------------------------------------------------------- local Config = class('Config') function Config:initialize(data) data = data or mw.loadData('Module:Protection banner/config') self._cfg = data.cfg self._msg = data.msg self._bannerConfigTables = {} end function Config:getBannerConfig(protectionObj) if self._bannerConfigTables[protectionObj] then return self._bannerConfigTables[protectionObj] else local ret = {} local cfg = self._cfg local action = protectionObj.action local level = protectionObj.level local reason = protectionObj.reason local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[action] then configTables[#configTables + 1] = cfg.banners[action][reason] end if cfg.defaultBanners[action] then configTables[#configTables + 1] = cfg.defaultBanners[action][level] configTables[#configTables + 1] = cfg.defaultBanners[action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then ret[field] = t[field] break end end end self._bannerConfigTables[protectionObj] = ret return ret end end function Config:getConfigTable(key) local blacklist = { banners = true, defaultBanners = true, masterBanner = true } if not blacklist[key] then return self._cfg[key] else return nil end end function Config:getMessage(key) return self._msg[key] end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj:getConfigTable('indefStrings') if indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') end function Protection:isProtected() return self._level ~= '*' end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = configObj:getBannerConfig(protectionObj) self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj:getMessage(msg) return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj:getConfigTable('imageLinks') local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj:getConfigTable('pagetypes') local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj:getConfigTable('protectionBlurbs') local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj:getConfigTable('protectionLevels') local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj:getMessage('image-filename-indef') return nil end -- Deal with regular protection types. local images = self._configObj:getConfigTable('images') if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj:getMessage('image-filename-default') or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj:getConfigTable('categoryNamespaceKeys') nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj.reason local action = protectionObj.action local level = protectionObj.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj:getConfigTable('reasonsWithNamespacePriority') local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj:getConfigTable('protectionCategories') local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local reasonsWithoutExpiryCheck = self._configObj:getConfigTable('reasonsWithoutExpiryCheck') local expiryCheckActions = self._configObj:getConfigTable('expiryCheckActions') local expiry = self._protectionObj.expiry local action = self._protectionObj.action local reason = self._protectionObj.reason if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj:getMessage('tracking-category-expiry')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj.expiry local action = protectionObj.action local level = protectionObj.level if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj:getMessage('tracking-category-incorrect')) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj:getMessage('tracking-category-template')) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects local configObj = Config:new() local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = configObj:getBannerConfig(protectionObj) bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Config = Config, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 2b0lv5jkzfxgo3bcd0jw2gtoimq29s4 28192 28191 2014-06-28T01:52:55Z w>Jackmcbarn 0 try to merge the edit conflict, one variable at a time, starting with action 28192 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang, config -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self._level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self._reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self._level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self._level ~= '*' end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj:getLevel() -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj:getLevel() local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj:getLevel() local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj:getLevel() local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj:getLevel() local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj:getLevel() local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj.action local level = protectionObj:getLevel() --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = configObj.cfg.expiryCheckActions local expiry = protectionObj:getExpiry() local action = protectionObj.action local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj.msg['tracking-category-expiry']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj.action local level = protectionObj:getLevel() if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj.msg['tracking-category-incorrect']) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj.action local level = protectionObj:getLevel() local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj.msg['tracking-category-template']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects if not config then config = mw.loadData('Module:Protection banner/config') end local configObj = config local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner jvt4x8rhss8n41n48r6rpqxflb78tjl 28193 28192 2014-06-28T01:54:19Z w>Jackmcbarn 0 now level 28193 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang, config -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self._reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self._reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj:getReason() local action = protectionObj.action local level = protectionObj.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = configObj.cfg.expiryCheckActions local expiry = protectionObj:getExpiry() local action = protectionObj.action local reason = protectionObj:getReason() if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj.msg['tracking-category-expiry']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj.action local level = protectionObj.level if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj.msg['tracking-category-incorrect']) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj.action local level = protectionObj.level local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj.msg['tracking-category-template']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects if not config then config = mw.loadData('Module:Protection banner/config') end local configObj = config local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner jtvwc243zy411lcqzskoyzitfyn1e55 28194 28193 2014-06-28T01:55:03Z w>Jackmcbarn 0 now reason 28194 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang, config -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self._expiry = 'indef' elseif type(args.expiry) == 'number' then self._expiry = args.expiry else self._expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj:getExpiry() if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj:getExpiry() if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj:getExpiry() local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj:getExpiry() if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj.reason local action = protectionObj.action local level = protectionObj.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = configObj.cfg.expiryCheckActions local expiry = protectionObj:getExpiry() local action = protectionObj.action local reason = protectionObj.reason if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj.msg['tracking-category-expiry']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj:getExpiry() local action = protectionObj.action local level = protectionObj.level if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj.msg['tracking-category-incorrect']) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj.action local level = protectionObj.level local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj.msg['tracking-category-template']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects if not config then config = mw.loadData('Module:Protection banner/config') end local configObj = config local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 9vqmv0sztw1t47741eilt86nvhh3ymj 28195 28194 2014-06-28T01:55:59Z w>Jackmcbarn 0 next expiry 28195 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang, config -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self._protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj:getProtectionDate() if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj:getProtectionDate() if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj.reason local action = protectionObj.action local level = protectionObj.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = configObj.cfg.expiryCheckActions local expiry = protectionObj.expiry local action = protectionObj.action local reason = protectionObj.reason if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj.msg['tracking-category-expiry']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj.expiry local action = protectionObj.action local level = protectionObj.level if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj.msg['tracking-category-incorrect']) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj.action local level = protectionObj.level local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj.msg['tracking-category-template']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects if not config then config = mw.loadData('Module:Protection banner/config') end local configObj = config local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner jipo144hbej62js11aqdsikhrl72beg 28196 28195 2014-06-28T01:56:54Z w>Jackmcbarn 0 and finally protectionDate 28196 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang, config -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj.reason local action = protectionObj.action local level = protectionObj.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local reasonsWithoutExpiryCheck = configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = configObj.cfg.expiryCheckActions local expiry = protectionObj.expiry local action = protectionObj.action local reason = protectionObj.reason if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(configObj.msg['tracking-category-expiry']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj.expiry local action = protectionObj.action local level = protectionObj.level if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj.msg['tracking-category-incorrect']) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj local action = protectionObj.action local level = protectionObj.level local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj.msg['tracking-category-template']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects if not config then config = mw.loadData('Module:Protection banner/config') end local configObj = config local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner fdxq99cdwts1xecary75lornbddr69o 28197 28196 2014-06-28T02:01:16Z w>Jackmcbarn 0 get a few other changes from the ec 28197 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang, config -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj.reason local action = protectionObj.action local level = protectionObj.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local reasonsWithoutExpiryCheck = self._configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = self._configObj.cfg.expiryCheckActions local expiry = self._protectionObj.expiry local action = self._protectionObj.action local reason = self._protectionObj.reason if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(self._configObj.msg['tracking-category-expiry']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj.expiry local action = protectionObj.action local level = protectionObj.level if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj.msg['tracking-category-incorrect']) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local titleObj = self._titleObj local action = self._protectionObj.action local level = self._protectionObj.level local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj.msg['tracking-category-template']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, titleObj) end function ProtectionBanner.exportToLua(args, titleObj) titleObj = titleObj or mw.title.getCurrentTitle() -- Get data objects if not config then config = mw.loadData('Module:Protection banner/config') end local configObj = config local protectionObj = Protection:new(args, configObj, titleObj) -- Initialise the blurb object local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner n5jkr4i596tt3vmt1c7j0fa4z8qrnd5 28198 28197 2014-06-28T12:51:08Z w>Mr. Stradivarius 0 allow passing the config object into the exportToLua and exportToWiki functions 28198 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Category class -------------------------------------------------------------------------------- local Category = class('Category') function Category:initialize(configObj, protectionObj) self._configObj = configObj self._protectionObj = protectionObj end function Category:setName(name) self._name = name end function Category:render() if self._name then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, self._name ) end end -------------------------------------------------------------------------------- -- ProtectionCategory class -------------------------------------------------------------------------------- local ProtectionCategory = Category:subclass('ProtectionCategory') function ProtectionCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function ProtectionCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local titleObj = self._titleObj -- Get the level and exit if the page is not protected. if not protectionObj:isProtected() then return '' end -- Get the expiry. local expiry = protectionObj.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = protectionObj.reason local action = protectionObj.action local level = protectionObj.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end if cat then self:setName(cat) end return Category.render(self) end -------------------------------------------------------------------------------- -- ExpiryCategory class -------------------------------------------------------------------------------- local ExpiryCategory = Category:subclass('ExpiryCategory') function ExpiryCategory:render() local reasonsWithoutExpiryCheck = self._configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = self._configObj.cfg.expiryCheckActions local expiry = self._protectionObj.expiry local action = self._protectionObj.action local reason = self._protectionObj.reason if not expiry and expiryCheckActions[action] and reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[reason] then self:setName(self._configObj.msg['tracking-category-expiry']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ErrorCategory class -------------------------------------------------------------------------------- local ErrorCategory = Category:subclass('ErrorCategory') function ErrorCategory:render() local configObj = self._configObj local protectionObj = self._protectionObj local expiry = protectionObj.expiry local action = protectionObj.action local level = protectionObj.level if not protectionObj:isProtected() or type(expiry) == 'number' and expiry < os.time() then self:setName(configObj.msg['tracking-category-incorrect']) end return Category.render(self) end -------------------------------------------------------------------------------- -- TemplateCategory class -------------------------------------------------------------------------------- local TemplateCategory = Category:subclass('TemplateCategory') function TemplateCategory:initialize(configObj, protectionObj, titleObj) Category.initialize(self, configObj, protectionObj) self._titleObj = titleObj end function TemplateCategory:render() local configObj = self._configObj local titleObj = self._titleObj local action = self._protectionObj.action local level = self._protectionObj.level local namespace = titleObj.namespace if level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then self:setName(configObj.msg['tracking-category-template']) end return Category.render(self) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, configObj, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, configObj, titleObj) end function ProtectionBanner.exportToLua(args, configObj, titleObj) configObj = configObj or mw.loadData('Module:Protection banner/config') titleObj = titleObj or mw.title.getCurrentTitle() -- Initialise protection and blurb objects local protectionObj = Protection:new(args, configObj, titleObj) local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then local objects = { ProtectionCategory:new(configObj, protectionObj, titleObj), ExpiryCategory:new(configObj, protectionObj), ErrorCategory:new(configObj, protectionObj), TemplateCategory:new(configObj, protectionObj, titleObj) } for _, obj in ipairs(objects) do ret[#ret + 1] = obj:render() end end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, Category = Category, ProtectionCategory = ProtectionCategory, ErrorCategory = ErrorCategory, ExpiryCategory = ExpiryCategory, } end return ProtectionBanner 2wbospq541b423lk4e52s0q70lsxqaa 28199 28198 2014-06-28T13:54:20Z w>Mr. Stradivarius 0 move the category methods to the Protection class, and get rid of all the category objects 28199 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) self._configObj = configObj self._titleObj = titleObj -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection._makeCategoryLink(cat) -- Static method for rendering category wikitext. if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end function Protection:makeProtectionCategory() local configObj = self._configObj local titleObj = self._titleObj -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end return self._makeCategoryLink(cat) end function Protection:makeExpiryCategory() local reasonsWithoutExpiryCheck = self._configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = self._configObj.cfg.expiryCheckActions local cat if not self.expiry and expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[self.reason] then cat = self._configObj.msg['tracking-category-expiry'] end return self._makeCategoryLink(cat) end function Protection:makeErrorCategory() local configObj = self._configObj local cat if not self:isProtected() or type(self.expiry) == 'number' and self.expiry < os.time() then cat = configObj.msg['tracking-category-incorrect'] end return self._makeCategoryLink(cat) end function Protection:makeTemplateCategory() local configObj = self._configObj local titleObj = self._titleObj local cat if self.level == 'templateeditor' and ( (self.action ~= 'edit' and self.action ~= 'move') or (titleObj.namespace ~= 10 and titleObj.namespace ~= 828) ) then cat = configObj.msg['tracking-category-template'] end return self._makeCategoryLink(cat) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end function BannerTemplate:render() -- Dummy method, to be implemented by the subclasses. return '' end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:render(page) -- Renders the banner. -- The page parameter specifies the page to generate the banner for, for -- testing purposes. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:render() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, configObj, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, configObj, titleObj) end function ProtectionBanner.exportToLua(args, configObj, titleObj) configObj = configObj or mw.loadData('Module:Protection banner/config') titleObj = titleObj or mw.title.getCurrentTitle() -- Initialise protection and blurb objects local protectionObj = Protection:new(args, configObj, titleObj) local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) end ret[#ret + 1] = bannerObj:render() end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end return ProtectionBanner o8bz1hn7ry2udzyzhwynroi06t6pdgy 28200 28199 2014-06-28T14:18:55Z w>Mr. Stradivarius 0 use a __tostring metamethod to render the banner objects 28200 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') function Protection:initialize(args, configObj, titleObj) self._configObj = configObj self._titleObj = titleObj -- Set action do local actions = { create = true, edit = true, move = true, autoreview = true } if args.action and actions[args.action] then self.action = args.action else self.action = 'edit' end end -- Set level do local level = effectiveProtectionLevel(self.action, titleObj) if level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. level = 'templateeditor' end if self.action == 'move' and level == 'autoconfirmed' then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. level = '*' end self.level = level or '*' end -- Validation function for the expiry and the protection date local function validateDate(date, dateType) lang = lang or mw.language.getContentLanguage() local success, expiry = pcall(lang.formatDate, lang, 'U', args.expiry) expiry = tonumber(expiry) if success and expiry then return expiry else return string.format( '<strong class="error">Error: invalid %s ("%s")</strong>', dateType, tostring(args.expiry) ) end end -- Set expiry if args.expiry then local indefStrings = configObj.cfg.indefStrings if indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local fields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(fields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection._makeCategoryLink(cat) -- Static method for rendering category wikitext. if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end function Protection:makeProtectionCategory() local configObj = self._configObj local titleObj = self._titleObj -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end return self._makeCategoryLink(cat) end function Protection:makeExpiryCategory() local reasonsWithoutExpiryCheck = self._configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = self._configObj.cfg.expiryCheckActions local cat if not self.expiry and expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[self.reason] then cat = self._configObj.msg['tracking-category-expiry'] end return self._makeCategoryLink(cat) end function Protection:makeErrorCategory() local configObj = self._configObj local cat if not self:isProtected() or type(self.expiry) == 'number' and self.expiry < os.time() then cat = configObj.msg['tracking-category-incorrect'] end return self._makeCategoryLink(cat) end function Protection:makeTemplateCategory() local configObj = self._configObj local titleObj = self._titleObj local cat if self.level == 'templateeditor' and ( (self.action ~= 'edit' and self.action ~= 'move') or (titleObj.namespace ~= 10 and titleObj.namespace ~= 828) ) then cat = configObj.msg['tracking-category-template'] end return self._makeCategoryLink(cat) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, configObj, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, configObj, titleObj) end function ProtectionBanner.exportToLua(args, configObj, titleObj) configObj = configObj or mw.loadData('Module:Protection banner/config') titleObj = titleObj or mw.title.getCurrentTitle() -- Initialise protection and blurb objects local protectionObj = Protection:new(args, configObj, titleObj) local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields and the page name. if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(titleObj.prefixedText) end ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end return ProtectionBanner 9sv1w89x0lizlxurr3sf6irqu5ej3f8 28201 28200 2014-06-28T17:18:15Z w>Jackmcbarn 0 some cleanup 28201 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, configObj, titleObj) self._configObj = configObj self._titleObj = titleObj -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, titleObj) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if configObj.cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj.cfg local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local configObj = self._configObj local titleObj = self._titleObj -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end return makeCategoryLink(cat) end function Protection:makeExpiryCategory() local reasonsWithoutExpiryCheck = self._configObj.cfg.reasonsWithoutExpiryCheck local expiryCheckActions = self._configObj.cfg.expiryCheckActions local cat if not self.expiry and expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[self.reason] then cat = self._configObj.msg['tracking-category-expiry'] end return makeCategoryLink(cat) end function Protection:makeErrorCategory() local configObj = self._configObj local cat if not self:isProtected() or type(self.expiry) == 'number' and self.expiry < os.time() then cat = configObj.msg['tracking-category-incorrect'] end return makeCategoryLink(cat) end function Protection:makeTemplateCategory() local configObj = self._configObj local titleObj = self._titleObj local cat if self.level == 'templateeditor' and ( (self.action ~= 'edit' and self.action ~= 'move') or (titleObj.namespace ~= 10 and titleObj.namespace ~= 828) ) then cat = configObj.msg['tracking-category-template'] end return makeCategoryLink(cat) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, configObj, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, configObj, titleObj) end function ProtectionBanner.exportToLua(args, configObj, titleObj) configObj = configObj or mw.loadData('Module:Protection banner/config') titleObj = titleObj or mw.title.getCurrentTitle() -- Initialise protection and blurb objects local protectionObj = Protection:new(args, configObj, titleObj) local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields and the page name. if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(titleObj.prefixedText) end ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end return ProtectionBanner jsslwc4ul1jju36zrfb1rk1m6idwz2d 28202 28201 2014-06-28T17:49:10Z w>Jackmcbarn 0 use new cfg format 28202 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, configObj, titleObj) self._configObj = configObj self._titleObj = titleObj -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, titleObj) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if configObj.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local cfg = configObj local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local configObj = self._configObj local titleObj = self._titleObj -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end return makeCategoryLink(cat) end function Protection:makeExpiryCategory() local reasonsWithoutExpiryCheck = self._configObj.reasonsWithoutExpiryCheck local expiryCheckActions = self._configObj.expiryCheckActions local cat if not self.expiry and expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[self.reason] then cat = self._configObj.msg['tracking-category-expiry'] end return makeCategoryLink(cat) end function Protection:makeErrorCategory() local configObj = self._configObj local cat if not self:isProtected() or type(self.expiry) == 'number' and self.expiry < os.time() then cat = configObj.msg['tracking-category-incorrect'] end return makeCategoryLink(cat) end function Protection:makeTemplateCategory() local configObj = self._configObj local titleObj = self._titleObj local cat if self.level == 'templateeditor' and ( (self.action ~= 'edit' and self.action ~= 'move') or (titleObj.namespace ~= 10 and titleObj.namespace ~= 828) ) then cat = configObj.msg['tracking-category-template'] end return makeCategoryLink(cat) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for cfg.protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for cfg.protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, configObj, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, configObj, titleObj) end function ProtectionBanner.exportToLua(args, configObj, titleObj) configObj = configObj or mw.loadData('Module:Protection banner/config') titleObj = titleObj or mw.title.getCurrentTitle() -- Initialise protection and blurb objects local protectionObj = Protection:new(args, configObj, titleObj) local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields and the page name. if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(titleObj.prefixedText) end ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end return ProtectionBanner qjrigrwljgedzbo2trkvuzt84vo3dph 28203 28202 2014-06-28T17:50:38Z w>Jackmcbarn 0 simplify further 28203 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, configObj, titleObj) self._configObj = configObj self._titleObj = titleObj -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, titleObj) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if configObj.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if configObj.banners[self.action] then configTables[#configTables + 1] = configObj.banners[self.action][self.reason] end if configObj.defaultBanners[self.action] then configTables[#configTables + 1] = configObj.defaultBanners[self.action][self.level] configTables[#configTables + 1] = configObj.defaultBanners[self.action].default end configTables[#configTables + 1] = configObj.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local configObj = self._configObj local titleObj = self._titleObj -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = configObj.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = configObj.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = configObj.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end return makeCategoryLink(cat) end function Protection:makeExpiryCategory() local reasonsWithoutExpiryCheck = self._configObj.reasonsWithoutExpiryCheck local expiryCheckActions = self._configObj.expiryCheckActions local cat if not self.expiry and expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[self.reason] then cat = self._configObj.msg['tracking-category-expiry'] end return makeCategoryLink(cat) end function Protection:makeErrorCategory() local configObj = self._configObj local cat if not self:isProtected() or type(self.expiry) == 'number' and self.expiry < os.time() then cat = configObj.msg['tracking-category-incorrect'] end return makeCategoryLink(cat) end function Protection:makeTemplateCategory() local configObj = self._configObj local titleObj = self._titleObj local cat if self.level == 'templateeditor' and ( (self.action ~= 'edit' and self.action ~= 'move') or (titleObj.namespace ~= 10 and titleObj.namespace ~= 828) ) then cat = configObj.msg['tracking-category-template'] end return makeCategoryLink(cat) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(configObj, protectionObj, titleObj) self._configObj = configObj self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._configObj.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._configObj.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._configObj.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._configObj.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._configObj.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(configObj) self._configObj = configObj end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._configObj.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._configObj.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._configObj.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(configObj) BannerTemplate.initialize(self, configObj) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, configObj, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, configObj, titleObj) end function ProtectionBanner.exportToLua(args, configObj, titleObj) configObj = configObj or mw.loadData('Module:Protection banner/config') titleObj = titleObj or mw.title.getCurrentTitle() -- Initialise protection and blurb objects local protectionObj = Protection:new(args, configObj, titleObj) local blurbObj = Blurb:new(configObj, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(configObj) else bannerObj = Banner:new(configObj) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields and the page name. if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(titleObj.prefixedText) end ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end return ProtectionBanner 9frdpqfhewiv8otabz1hi9wv8lbsrri 28204 28203 2014-06-28T17:53:04Z w>Jackmcbarn 0 config isn't an object anymore 28204 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local mArguments, mMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, titleObj) self._cfg = cfg self._titleObj = titleObj -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, titleObj) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local titleObj = self._titleObj -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = titleObj.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end return makeCategoryLink(cat) end function Protection:makeExpiryCategory() local reasonsWithoutExpiryCheck = self._cfg.reasonsWithoutExpiryCheck local expiryCheckActions = self._cfg.expiryCheckActions local cat if not self.expiry and expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[self.reason] then cat = self._cfg.msg['tracking-category-expiry'] end return makeCategoryLink(cat) end function Protection:makeErrorCategory() local cfg = self._cfg local cat if not self:isProtected() or type(self.expiry) == 'number' and self.expiry < os.time() then cat = cfg.msg['tracking-category-incorrect'] end return makeCategoryLink(cat) end function Protection:makeTemplateCategory() local cfg = self._cfg local titleObj = self._titleObj local cat if self.level == 'templateeditor' and ( (self.action ~= 'edit' and self.action ~= 'move') or (titleObj.namespace ~= 10 and titleObj.namespace ~= 828) ) then cat = cfg.msg['tracking-category-template'] end return makeCategoryLink(cat) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(cfg, protectionObj, titleObj) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._titleObj = titleObj end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._cfg.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._titleObj.namespace local isTalk = self._titleObj.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._titleObj.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._titleObj.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._titleObj.namespace].talk.name, self._titleObj.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._titleObj.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(cfg) self._cfg = cfg end function BannerTemplate:setImageFilename(filename, protectionObj, titleObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = titleObj.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. mMessageBox = mMessageBox or require('Module:Message box') local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return mMessageBox.main('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- ProtectionBanner class -------------------------------------------------------------------------------- local ProtectionBanner = {} function ProtectionBanner.exportToWiki(frame, cfg, titleObj) mArguments = mArguments or require('Module:Arguments') local args = mArguments.getArgs(frame) return ProtectionBanner.exportToLua(args, cfg, titleObj) end function ProtectionBanner.exportToLua(args, cfg, titleObj) cfg = cfg or mw.loadData('Module:Protection banner/config') titleObj = titleObj or mw.title.getCurrentTitle() -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, titleObj) local blurbObj = Blurb:new(cfg, protectionObj, titleObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(cfg) else bannerObj = Banner:new(cfg) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj, titleObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields and the page name. if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(titleObj.prefixedText) end ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function ProtectionBanner._exportClasses() -- This is used to export the classes for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end return ProtectionBanner ljelz2ab8u8sxkk2ogu1a262nblqmup 28205 28204 2014-06-28T18:05:31Z w>Jackmcbarn 0 make the Protection class be in charge of the title, and some other tweaks 28205 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg) self._cfg = cfg if args.title then self.title = mw.title.new(args.title) if not self.title then error('Invalid title "' .. args.title .. '"', 2) end else self.title = mw.title.getCurrentTitle() end -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = title.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories local cat for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then cat = attempt break end end return makeCategoryLink(cat) end function Protection:makeExpiryCategory() local reasonsWithoutExpiryCheck = self._cfg.reasonsWithoutExpiryCheck local expiryCheckActions = self._cfg.expiryCheckActions local cat if not self.expiry and expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not reasonsWithoutExpiryCheck[self.reason] then cat = self._cfg.msg['tracking-category-expiry'] end return makeCategoryLink(cat) end function Protection:makeErrorCategory() local cfg = self._cfg local cat if not self:isProtected() or type(self.expiry) == 'number' and self.expiry < os.time() then cat = cfg.msg['tracking-category-incorrect'] end return makeCategoryLink(cat) end function Protection:makeTemplateCategory() local cfg = self._cfg local title = self.title local cat if self.level == 'templateeditor' and ( (self.action ~= 'edit' and self.action ~= 'move') or (title.namespace ~= 10 and title.namespace ~= 828) ) then cat = cfg.msg['tracking-category-template'] end return makeCategoryLink(cat) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(cfg, protectionObj) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title end -- Static methods -- function Blurb.makeFullUrl(page, query, display) local url = mw.uri.fullUrl(page, query) url = tostring(url) return string.format('[%s %s]', url, display) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msg) local msg = self._cfg.msg[msg] return self:_substituteParameters(msg) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(cfg) self._cfg = cfg end function BannerTemplate:setImageFilename(filename, protectionObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg) local blurbObj = Blurb:new(cfg, protectionObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(cfg) else bannerObj = Banner:new(cfg) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields and the page name. if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(protectionObj.title.prefixedText) end ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p imbc5p99yn4jyw51iylavkiro4dd7t7 28206 28205 2014-06-28T18:16:10Z w>Jackmcbarn 0 rm some locals that only get used once 28206 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg) self._cfg = cfg if args.title then self.title = mw.title.new(args.title) if not self.title then error('Invalid title "' .. args.title .. '"', 2) end else self.title = mw.title.getCurrentTitle() end -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = title.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:makeExpiryCategory() local cfg = self._cfg if not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] then return makeCategoryLink(self._cfg.msg['tracking-category-expiry']) end end function Protection:makeErrorCategory() local expiry = self.expiry if not self:isProtected() or type(expiry) == 'number' and expiry < os.time() then return makeCategoryLink(self._cfg.msg['tracking-category-incorrect']) end end function Protection:makeTemplateCategory() local action, namespace = self.action, self.title.namespace if self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then return makeCategoryLink(self._cfg.msg['tracking-category-template']) end end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(cfg, protectionObj) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(cfg) self._cfg = cfg end function BannerTemplate:setImageFilename(filename, protectionObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg) local blurbObj = Blurb:new(cfg, protectionObj) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local isPadlock = yesno(args.small) local bannerObj if isPadlock then bannerObj = Padlock:new(cfg) else bannerObj = Banner:new(cfg) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj) if isPadlock then bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) end -- Set the text fields and the page name. if not isPadlock then bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(protectionObj.title.prefixedText) end ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p 7z66og4mxryfkt9tdard6tciz1uurdz 28207 28206 2014-06-28T18:19:35Z w>Jackmcbarn 0 condense _main and switch Blurb arg order 28207 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg) self._cfg = cfg if args.title then self.title = mw.title.new(args.title) if not self.title then error('Invalid title "' .. args.title .. '"', 2) end else self.title = mw.title.getCurrentTitle() end -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = title.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:makeExpiryCategory() local cfg = self._cfg if not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] then return makeCategoryLink(self._cfg.msg['tracking-category-expiry']) end end function Protection:makeErrorCategory() local expiry = self.expiry if not self:isProtected() or type(expiry) == 'number' and expiry < os.time() then return makeCategoryLink(self._cfg.msg['tracking-category-incorrect']) end end function Protection:makeTemplateCategory() local action, namespace = self.action, self.title.namespace if self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then return makeCategoryLink(self._cfg.msg['tracking-category-template']) end end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:setDeletionDiscussionPage(page) self._deletionDiscussionPage = page end function Blurb:setUsername(username) self._username = username end function Blurb:setSection(section) self._section = section end function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(cfg) self._cfg = cfg end function BannerTemplate:setImageFilename(filename, protectionObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg) local blurbObj = Blurb:new(protectionObj, cfg) blurbObj:setDeletionDiscussionPage(args.xfd) blurbObj:setUsername(args.user) blurbObj:setSection(args.section) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local bannerObj if yesno(args.small) then bannerObj = Padlock:new(cfg) bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else bannerObj = Banner:new(cfg) -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) -- Set the text fields and the page name. bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(protectionObj.title.prefixedText) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj) ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p e0ssta5s9mnadlo2ano8tlp1xat3q0z 28208 28207 2014-06-28T18:31:23Z w>Jackmcbarn 0 make Blurb be responsible for setting its own fields 28208 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg) self._cfg = cfg if args.title then self.title = mw.title.new(args.title) if not self.title then error('Invalid title "' .. args.title .. '"', 2) end else self.title = mw.title.getCurrentTitle() end -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = title.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:makeExpiryCategory() local cfg = self._cfg if not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] then return makeCategoryLink(self._cfg.msg['tracking-category-expiry']) end end function Protection:makeErrorCategory() local expiry = self.expiry if not self:isProtected() or type(expiry) == 'number' and expiry < os.time() then return makeCategoryLink(self._cfg.msg['tracking-category-incorrect']) end end function Protection:makeTemplateCategory() local action, namespace = self.action, self.title.namespace if self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) then return makeCategoryLink(self._cfg.msg['tracking-category-template']) end end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(cfg) self._cfg = cfg end function BannerTemplate:setImageFilename(filename, protectionObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local bannerObj if yesno(args.small) then bannerObj = Padlock:new(cfg) bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else bannerObj = Banner:new(cfg) -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) -- Set the text fields and the page name. bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(protectionObj.title.prefixedText) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj) ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeProtectionCategory() ret[#ret + 1] = protectionObj:makeExpiryCategory() ret[#ret + 1] = protectionObj:makeErrorCategory() ret[#ret + 1] = protectionObj:makeTemplateCategory() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p 29110rfla40hh06ptmsb8ysu1owa4ib 28209 28208 2014-06-28T18:40:39Z w>Jackmcbarn 0 put Protection in charge of generating its own category links 28209 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg) self._cfg = cfg if args.title then self.title = mw.title.new(args.title) if not self.title then error('Invalid title "' .. args.title .. '"', 2) end else self.title = mw.title.getCurrentTitle() end -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = title.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(cfg) self._cfg = cfg end function BannerTemplate:setImageFilename(filename, protectionObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local bannerObj if yesno(args.small) then bannerObj = Padlock:new(cfg) bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else bannerObj = Banner:new(cfg) -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) -- Set the text fields and the page name. bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(protectionObj.title.prefixedText) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj) ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p o8nbqy06sjxpecxr8yor2go4th3wqzw 28210 28209 2014-06-28T19:00:58Z w>Jackmcbarn 0 the only reason to ever use a title other than the current one is for testing, so don't bother exposing it to wikitext 28210 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = title.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(cfg) self._cfg = cfg end function BannerTemplate:setImageFilename(filename, protectionObj) if filename then self._imageFilename = filename return nil end local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] return nil end -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] return nil elseif images[action].default then self._imageFilename = images[action].default return nil end end return nil end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(40) end function Banner:setReasonText(s) self._reasonText = s end function Banner:setExplanationText(s) self._explanationText = s end function Banner:setPage(s) -- This specifies the page to generate the banner for. This only affects -- Module:Message box if the page specified is not the current page. self._page = s end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(cfg) BannerTemplate.initialize(self, cfg) self:setImageWidth(20) end function Padlock:setImageAlt(alt) self._imageAlt = alt end function Padlock:setImageLink(link) self._imageLink = link end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then -- Get the banner object local bannerObj if yesno(args.small) then bannerObj = Padlock:new(cfg) bannerObj:setImageTooltip(blurbObj:makeTooltipText()) bannerObj:setImageAlt(blurbObj:makeAltText()) bannerObj:setImageLink(blurbObj:makeLinkText()) else bannerObj = Banner:new(cfg) -- Large banners use the alt text for the tooltip. bannerObj:setImageTooltip(blurbObj:makeAltText()) -- Set the text fields and the page name. bannerObj:setReasonText(blurbObj:makeReasonText()) bannerObj:setExplanationText(blurbObj:makeExplanationText()) bannerObj:setPage(protectionObj.title.prefixedText) end -- Set the image fields local bannerConfig = protectionObj.bannerConfig bannerObj:setImageFilename(bannerConfig.image, protectionObj) ret[#ret + 1] = tostring(bannerObj) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p lvtkrwj3crqkrimvdut96yi0eoc4476 28211 28210 2014-06-28T22:17:43Z w>Jackmcbarn 0 make the banner in charge of setting its own fields 28211 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action do if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end end -- Set level do self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = title.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- This only affects Module:Message box if the page specified is not the current page. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p kwugrpexz16iac16g0yir8r8q7hbm4t 28212 28211 2014-06-28T22:27:32Z w>Jackmcbarn 0 rm unnecessary do/end blocks 28212 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry. local expiry = self.expiry if type(expiry) == 'number' then expiry = 'temp' elseif expiry ~= 'indef' then expiry = nil end -- Get the namespace category key. local nskey do local namespace = title.namespace local categoryNamespaces = cfg.categoryNamespaceKeys nskey = categoryNamespaces[namespace] if not nskey and namespace % 2 == 1 then nskey = 'talk' end end -- Get the other inputs. local reason = self.reason local action = self.action local level = self.level --[[ -- Define the properties table. Each property is a table containing the -- canonical order that the property is tested in, the position the -- property has in the category key strings, and the property value itself. --]] local properties = { expiry = {order = 1, val = expiry}, namespace = {order = 2, val = nskey}, reason = {order = 3, val = reason}, level = {order = 4, val = level}, action = {order = 5, val = action} } --[[ -- Apply the category order configuration, if any. The configuration value -- will be a property string, e.g. 'reason', 'namespace', etc. The property -- corresponding to that string is tested last (i.e. it is the most -- important, because it keeps its specified value the longest) and the -- other properties are tested in the canonical order. If no configuration -- value is specified then the canonical order is used. --]] local configOrder = {} do local reasonsWithNamespacePriority = cfg.reasonsWithNamespacePriority local namespaceFirst = reason and reasonsWithNamespacePriority[reason] or false for propertiesKey, t in pairs(properties) do configOrder[t.order] = t end if namespaceFirst then -- Swap namespace and reason around. local namespaceTable = table.remove(configOrder, 2) table.insert(configOrder, 3, namespaceTable) end end --[[ -- Define the attempt order. Properties with no value defined are moved -- to the end, where they will later be given the value "all". This is -- to cut down on the number of table lookups in the cats table, which -- grows exponentially with the number of properties with valid values. -- We keep track of the number of active properties with the noActive -- parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(configOrder) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. -- If a specific category exists for the combination of properties -- we are given, that match will be found first. If not, we keep -- trying different key combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the property subtables using a -- binary matrix with indexes i and j. j is only calculated up to -- the number of active properties. For example, if there were three -- active properties, the matrix would look like this, with 0 -- corresponding to the string "all", and 1 corresponding to the -- val field in the property table: -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active properties are set -- to the string "all". -- -- A key for the category table is constructed for each value of i. -- The correct position of the value in the key is determined by the -- pos field in the property table. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.order] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.order] = t.val else key[t.order] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- This only affects Module:Message box if the page specified is not the current page. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p ilfi4e7mgj5vlbv5h0kdlj1a0rl4dn6 28213 28212 2014-06-29T03:53:20Z w>Mr. Stradivarius 0 simplify Protection:makeProtectionCategory and update the comments 28213 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- This only affects Module:Message box if the page specified is not the current page. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() end function Padlock:setRight(px) self._right = px end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right or '55px'} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p lsvk00vn07dtsyka2950is3xdu3p250 28214 28213 2014-06-29T10:49:09Z w>Mr. Stradivarius 0 use the config to set the padlock "right" propery, and remove the Padlock:setRight method 28214 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- This only affects Module:Message box if the page specified is not the current page. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p 8js55binuveg4z8g0q3tr9orteqs1nb 28215 28214 2014-06-29T10:50:24Z w>Mr. Stradivarius 0 fix variable name 28215 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then local xfd = self._deletionDiscussion if xfd then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- This only affects Module:Message box if the page specified is not the current page. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p 6omuygaxuun4hvtrdfdn6alddai06n5 28216 28215 2014-06-29T10:54:39Z w>Mr. Stradivarius 0 remove another unnecessary local 28216 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._bannerConfig = protectionObj.bannerConfig self._title = protectionObj.title self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._title.namespace local isTalk = self._title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then if self._deletionDiscussion then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._title.namespace].talk.name, self._title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- This only affects Module:Message box if the page specified is not the current page. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p 6o65csql5qw1yr8z7axalhng4v0pif2 28217 28216 2014-06-29T11:06:00Z w>Mr. Stradivarius 0 make the protection object responsible for accessing the title object and the config inside the Blurb class 28217 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local action = self._protectionObj.action local pagename = self._protectionObj.title.prefixedText if action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() local deletionDiscussionPage = self._deletionDiscussionPage if deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local section = self._section local disputes = self:_getExpandedMessage('dispute-section-link-display') if section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then if self._deletionDiscussion then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes local namespace = self._protectionObj.title.namespace return pagetypes[namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local action = self._protectionObj.action local pagename = self._protectionObj.title.prefixedText if action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() local protectionDate = self._protectionObj.protectionDate if protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() local section = self._section local display = self:_getExpandedMessage('talk-page-link-display') return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, section or 'top', display ) end function Blurb:_makeTooltipBlurbParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() local mVandalM = require('Module:Vandal-m') local username = self._username username = username or self._protectionObj.title.baseText return mVandalM._main{username} end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- This only affects Module:Message box if the page specified is not the current page. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p bscxpuhzja700mcg74314i19j75t6oy 28218 28217 2014-06-29T11:34:02Z w>Mr. Stradivarius 0 get rid of a few more unnecessary local variables 28218 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() if self._deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', self._deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then if self._deletionDiscussion then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) -- Maybe we don't need the namespace check? and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- This only affects Module:Message box if the page specified is not the current page. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- this doesn't need the blurb self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p ee5y9lgcg1qzp3bpnlmxtgowxg2vu43 28219 28218 2014-06-29T11:49:44Z w>Mr. Stradivarius 0 comment tweaks 28219 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() if self._deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', self._deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then if self._deletionDiscussion then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._main(getArgs(frame)) end return p rjkh8pdf6koujce76tktk2uzbfupjyg 28220 28219 2014-06-29T12:51:13Z w>Mr. Stradivarius 0 specify [[Template:Pp]] as a wrapper for the module, and make args a local variable as otherwise it's a bit of a bracket overload 28220 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return self.makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return self.makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() if self._deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', self._deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then if self._deletionDiscussion then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return self.makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return self.makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p 8jkcrmsfpqnhgqs4j5cws5lhl9oeev9 28221 28220 2014-06-29T18:17:53Z w>Jackmcbarn 0 make makeFullUrl a local helper function 28221 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local params, parameterFuncs = {}, {} setmetatable(params, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' params[k] = param return param end }) parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = params end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() if self._deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', self._deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then if self._deletionDiscussion then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p 8yrk4r4h7iakkjo5mksvzkpmxl8jhne 28222 28221 2014-06-29T18:21:31Z w>Jackmcbarn 0 simplify _substituteParameters 28222 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() if self._deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', self._deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if expiry == 'indef' then return nil elseif type(expiry) == 'number' then return Blurb.formatDate(expiry) elseif expiry then -- Expiry is an error string. return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then if self._deletionDiscussion then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p 5njyzc4pcz0kvzkh1d60s1whctu3gai 28223 28222 2014-06-29T18:26:29Z w>Jackmcbarn 0 no need to special case indef expiry. if it's indef, the messages that get used don't use it anyway 28223 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { create = true, edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._deletionDiscussionPage = args.xfd self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DELETIONDISCUSSION = self._makeDeletionDiscussionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDeletionDiscussionLinkParameter() if self._deletionDiscussionPage then local display = self:_getExpandedMessage('deletion-discussion-link-display') return string.format('[[%s|%s]]', self._deletionDiscussionPage, display) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end elseif action == 'create' then if self._deletionDiscussion then key = 'explanation-blurb-create-xfd' else key = 'explanation-blurb-create-noxfd' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p enjbe9riv84xp06jokem6mavp89w3x9 28224 28223 2014-06-29T18:36:20Z w>Jackmcbarn 0 rm stuff only useful for pp-create and other things deprecated in favor of salting 28224 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = reason:lower() end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p dm3u71o32x0a8yt40wtbkimk9d0f6si 28225 28224 2014-06-30T03:06:37Z w>Mr. Stradivarius 0 use mw.ustring.lower to convert the reason to lower case, for the benefit of other-language wikis 28225 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) )) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error('Unsupported action ' .. args.action, 2) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = mw.ustring.lower(reason) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise protection and blurb objects local protectionObj = Protection:new(args, cfg, title) local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p gqrqznqw3vucr6p0pse5aw03a6vhxlh 28226 28225 2014-06-30T07:13:44Z w>Mr. Stradivarius 0 produce wikitext errors rather than script errors for errors caused by invalid user input 28226 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeWikitextError(msg) -- @TODO: localise this. local boilerplate = 'Error: $1 ([[Module:Protection banner#Errors|help]])' local errorText = mw.message.newRawMessage(boilerplate):params(msg):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = mw.ustring.lower(reason) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then -- protectionObj is the error message. return makeWikitextError(protectionObj) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p n0bnli4qmby29pydghkuxgo5pnmf2g4 28227 28226 2014-07-01T02:58:05Z w>Mr. Stradivarius 0 add a Documentation class for autogenerating the reason documentation 28227 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeWikitextError(msg) -- @TODO: localise this. local boilerplate = 'Error: $1 ([[Module:Protection banner#Errors|help]])' local errorText = mw.message.newRawMessage(boilerplate):params(msg):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = mw.ustring.lower(reason) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Documentation class -------------------------------------------------------------------------------- local Documentation = class('Documentation') function Documentation:initialize(cfg) self._cfg = cfg end function Documentation:makeReasonsTable() -- Get the data from the cfg.banners table. local rowData = {} for action, reasonTables in pairs(self._cfg.banners) do for reason, t in pairs(reasonTables) do rowData[#rowData + 1] = { reason = reason, action = action, description = t.description } end end -- Sort the table into alphabetical order, first by action and then by -- reason. table.sort(rowData, function (t1, t2) if t1.action == t2.action then return t1.reason < t2.reason else return t1.action < t2.action end end) -- Assemble a wikitable of the data. local msg = self._cfg.msg local ret = {} ret[#ret + 1] = '{| class="wikitable"' if #rowData < 1 then ret[#ret + 1] = '|-' ret[#ret + 1] = string.format( '| colspan="3" | %s', msg['documentation-blurb-noreasons'] ) else -- Header ret[#ret + 1] = '|-' ret[#ret + 1] = string.format( '! %s\n! %s\n! %s', msg['documentation-heading-reason'], msg['documentation-heading-action'], msg['documentation-heading-description'] ) -- Rows for _, t in ipairs(rowData) do ret[#ret + 1] = '|-' ret[#ret + 1] = string.format( '| %s\n| %s\n| %s', t.reason, t.action, t.description ) end end ret[#ret + 1] = '|}' return table.concat(ret, '\n') end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p.reasonTable() local cfg = mw.loadData('Module:Protection banner/config') local documentationObj = Documentation:new(cfg) return documentationObj:makeReasonsTable() end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then -- protectionObj is the error message. return makeWikitextError(protectionObj) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p 1k1sthayhjs7fe45ujbhsxeobe1cgjk 28228 28227 2014-07-01T03:03:37Z w>Mr. Stradivarius 0 call it "reasonTable" throughout, rather than switching between "reasonTable" and "reasonsTable" 28228 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeWikitextError(msg) -- @TODO: localise this. local boilerplate = 'Error: $1 ([[Module:Protection banner#Errors|help]])' local errorText = mw.message.newRawMessage(boilerplate):params(msg):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = mw.ustring.lower(reason) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Documentation class -------------------------------------------------------------------------------- local Documentation = class('Documentation') function Documentation:initialize(cfg) self._cfg = cfg end function Documentation:makeReasonTable() -- Get the data from the cfg.banners table. local rowData = {} for action, reasonTables in pairs(self._cfg.banners) do for reason, t in pairs(reasonTables) do rowData[#rowData + 1] = { reason = reason, action = action, description = t.description } end end -- Sort the table into alphabetical order, first by action and then by -- reason. table.sort(rowData, function (t1, t2) if t1.action == t2.action then return t1.reason < t2.reason else return t1.action < t2.action end end) -- Assemble a wikitable of the data. local msg = self._cfg.msg local ret = {} ret[#ret + 1] = '{| class="wikitable"' if #rowData < 1 then ret[#ret + 1] = '|-' ret[#ret + 1] = string.format( '| colspan="3" | %s', msg['documentation-blurb-noreasons'] ) else -- Header ret[#ret + 1] = '|-' ret[#ret + 1] = string.format( '! %s\n! %s\n! %s', msg['documentation-heading-reason'], msg['documentation-heading-action'], msg['documentation-heading-description'] ) -- Rows for _, t in ipairs(rowData) do ret[#ret + 1] = '|-' ret[#ret + 1] = string.format( '| %s\n| %s\n| %s', t.reason, t.action, t.description ) end end ret[#ret + 1] = '|}' return table.concat(ret, '\n') end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p.reasonTable() local cfg = mw.loadData('Module:Protection banner/config') local documentationObj = Documentation:new(cfg) return documentationObj:makeReasonTable() end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then -- protectionObj is the error message. return makeWikitextError(protectionObj) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p jdz9t3v2pxmdp8pykpfw4mio38yfbtc 28229 28228 2014-07-01T03:13:48Z w>Mr. Stradivarius 0 move documentation class and export function to [[Module:Protection banner/documentation]] 28229 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeWikitextError(msg) -- @TODO: localise this. local boilerplate = 'Error: $1 ([[Module:Protection banner#Errors|help]])' local errorText = mw.message.newRawMessage(boilerplate):params(msg):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args.reason or args[1] if reason then self.reason = mw.ustring.lower(reason) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then -- protectionObj is the error message. return makeWikitextError(protectionObj) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p n0bnli4qmby29pydghkuxgo5pnmf2g4 28230 28229 2014-07-01T03:18:00Z w>Jackmcbarn 0 no need for args.reason 28230 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeWikitextError(msg) -- @TODO: localise this. local boilerplate = 'Error: $1 ([[Module:Protection banner#Errors|help]])' local errorText = mw.message.newRawMessage(boilerplate):params(msg):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason do local reason = args[1] if reason then self.reason = mw.ustring.lower(reason) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then -- protectionObj is the error message. return makeWikitextError(protectionObj) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p 9slmbb2hqh6k1b3d2he313qx4vw9x2o 28231 28230 2014-07-01T06:56:34Z w>Mr. Stradivarius 0 simplify reason-setting code 28231 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeWikitextError(msg) -- @TODO: localise this. local boilerplate = 'Error: $1 ([[Module:Protection banner#Errors|help]])' local errorText = mw.message.newRawMessage(boilerplate):params(msg):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then -- protectionObj is the error message. return makeWikitextError(protectionObj) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p 3bemrg1bdfpuxfhyul5nh3xkif8kn4r 28232 28231 2014-07-01T07:25:32Z w>Mr. Stradivarius 0 make the args table optional from p._main 28232 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeWikitextError(msg) -- @TODO: localise this. local boilerplate = 'Error: $1 ([[Module:Protection banner#Errors|help]])' local errorText = mw.message.newRawMessage(boilerplate):params(msg):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then -- protectionObj is the error message. return makeWikitextError(protectionObj) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p rfoptfmyr1cnkk3ugxe784nhxq3hw1s 28233 28232 2014-07-03T07:04:23Z w>Mr. Stradivarius 0 localise the error message by moving the makeWikitextError function code inside p._main; that way we don't have to worry about making cfg global 28233 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local msg = protectionObj -- protectionObj is the error message. local boilerplate = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(boilerplate):params(msg):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p d9reqc4zb45n2dxqgsuqx0a6767lnus 28234 28233 2014-07-03T07:07:58Z w>Mr. Stradivarius 0 make the variable names a little more descriptive 28234 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorMessage = protectionObj local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb):params(errorMessage):plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p rcleaw57d3pn8haer6snzh0zhqywzdg 28235 28234 2014-07-03T07:11:16Z w>Mr. Stradivarius 0 use a comment instead of a variable assignment to make it clear that protectionObj is the error message 28235 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._username = args.user self._section = args.section end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeReasonText() local msg = self._protectionObj.bannerConfig.text if msg then return self:_substituteParameters(msg) end end function Blurb:makeExplanationText() local msg = self._protectionObj.bannerConfig.explanation return self:_substituteParameters(msg) end function Blurb:makeTooltipText() local msg = self._protectionObj.bannerConfig.tooltip return self:_substituteParameters(msg) end function Blurb:makeAltText() local msg = self._protectionObj.bannerConfig.alt return self:_substituteParameters(msg) end function Blurb:makeLinkText() local msg = self._protectionObj.bannerConfig.link return self:_substituteParameters(msg) end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeAltText()) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeReasonText() self._explanationText = blurbObj:makeExplanationText() self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeTooltipText()) self._imageAlt = blurbObj:makeAltText() self._imageLink = blurbObj:makeLinkText() self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = mw.loadData('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p nv1qsymvjhh7fhjknqt0a228zlc3qk0 28236 28235 2014-07-03T11:50:51Z w>Mr. Stradivarius 0 allow bannerConfig table fields to be functions 28236 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._data = { username = args.user, section = args.section } end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._data.section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._data.section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._data.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._data.username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._data) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = require('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p f64qrbguu9pmzrgtgmq197n9bgu1bgj 28237 28236 2014-07-03T11:53:45Z w>Mr. Stradivarius 0 remove unnecessary whitespace and copy edit one of the error messages 28237 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._data = { username = args.user, section = args.section } end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeDisputeBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('dispute-blurb-expiry') else return self:_getExpandedMessage('dispute-blurb-noexpiry') end end function Blurb:_makeDisputeSectionParameter() -- "disputes", with or without a section link local disputes = self:_getExpandedMessage('dispute-section-link-display') if self._data.section then return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._data.section, disputes ) else return disputes end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeOfficeBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('office-blurb-protectiondate') else return self:_getExpandedMessage('office-blurb-noprotectiondate') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeResetBlurbParameter() if self._protectionObj.protectionDate then return self:_getExpandedMessage('reset-blurb-protectiondate') else return self:_getExpandedMessage('reset-blurb-noprotectiondate') end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._data.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._data.username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._data) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = require('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p icw2rbmmwy9c2lqdiqfbifix059f17c 28238 28237 2014-07-03T16:12:51Z w>Mr. Stradivarius 0 remove parameter methods specific to individual reasons - the logic has been moved to [[Moudle:Protection banner/config]] 28238 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } -- To generate the correct category for some reason values, we need to -- prioritise the position of the namespace key fragment over that of the -- reason key fragment. For these reasn values, swap the namespace subtable -- and the reason subtable around. if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then table.insert(order, 3, table.remove(order, 2)) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._data = { username = args.user, section = args.section } end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._data.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._data.username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._data) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = require('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p dusgrmjaw1v9uxhesqgzmo0bjc68j1f 28239 28238 2014-07-04T07:38:11Z w>Mr. Stradivarius 0 Fix Protection:makeProtectionCategory for office-protected pages. For these, the reason needs to be the no. 1 priority, not just higher priority than the namespace. 28239 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._data = { username = args.user, section = args.section } end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._data.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._data.username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._data) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = require('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = 'Template:Pp'}) return p._main(args) end return p hlw3uk9hescw2uhgolmhnixzmuppv6i 28240 28239 2014-07-05T03:09:40Z w>Mr. Stradivarius 0 don't use the wrapper option with [[Module:Arguments]], as it prevents us from passing through parameters from the parent frame 28240 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._data = { username = args.user, section = args.section } end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._data.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._data.username or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._data) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = require('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame) return p._main(args) end return p kocaejszf3i84f4g1w852kf2qw2r41r 28241 28240 2014-07-06T14:44:00Z w>Mr. Stradivarius 0 just pass the args through to the /config functions - that means the /config functions can use arbitrary parameters without them having to be specified in the main module 28241 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '-') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = require('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame) return p._main(args) end return p ohlns5qvl24lqtv7dr9jh9kl5telin8 28242 28241 2014-07-06T14:56:56Z w>Mr. Stradivarius 0 use pipes as separators instead of hyphens for the protection category keys and validate reasons when we create the protection object to make sure they don't contain pipes 28242 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} if not cfg then cfg = require('Module:Protection banner/config') end -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame) return p._main(args) end return p fgjtmjk75564f2h5oltc8bpqcd7il6f 28243 28242 2014-07-06T15:16:33Z w>Mr. Stradivarius 0 allow reading wrapper templates and default arguments from the config page 28243 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local defaultArgs = cfg.wrappers[frame:getParent():getTitle()] local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs or {}) do args[k] = v end return p._main(args, cfg) end return p hlty6mi7gerg0uxm9kyf51cgeyjqyob 28244 28243 2014-07-10T01:03:20Z w>Mr. Stradivarius 0 allow default args to work in sandbox pages 28244 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>', errorText ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 6046twzu9ynwhww2c1362cxum7yfzjc 28245 28244 2014-07-10T01:10:00Z w>Mr. Stradivarius 0 output an error category if the protection object is not created properly 28245 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p b7fowntink80kkok98ru8sibhmfjr61 28246 28245 2014-07-10T01:18:13Z w>Mr. Stradivarius 0 get the expiry date format from a config message 28246 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Static methods -- function Blurb.formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end -- Private methods -- function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return Blurb.formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return Blurb.formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 90klg2jwd1oep2drzmxeygp8nkm14e5 28247 28246 2014-07-10T01:21:50Z w>Mr. Stradivarius 0 turn Blurb.formatDate into Blurb:_formatDate so that it can access the config 28247 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add semi-protection and pending changes blurbs local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p g7w3gn34dz0ein970ro1qe3fi3gluf4 28248 28247 2014-07-10T03:45:40Z w>Mr. Stradivarius 0 add explanation blurb for semi-protection 28248 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() local action = self._protectionObj.action local level = self._protectionObj.level local namespace = self._protectionObj.title.namespace local isTalk = self._protectionObj.title.isTalkPage -- @TODO: add pending changes local key if namespace == 8 then -- MediaWiki namespace key = 'explanation-blurb-full-nounprotect' elseif action == 'edit' and level == 'sysop' and not isTalk then key = 'explanation-blurb-full-subject' elseif action == 'edit' and level == 'autoconfirmed' then if isTalk then key = 'explanation-blurb-semi-talk' else key = 'explanation-blurb-semi-subject' end elseif action == 'move' then if isTalk then key = 'explanation-blurb-move-talk' else key = 'explanation-blurb-move-subject' end else key = 'explanation-blurb-default' end return self:_getExpandedMessage(key) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p agtzpcaudx287nx8el4t7jzr59bl2rj 28249 28248 2014-07-10T05:43:07Z w>Mr. Stradivarius 0 use cfg.explanationBlurbs to fetch the explanation blurbs rather than hard-coding the message keys here 28249 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date self.protectionDate = validateDate(args.date, 'protection date') -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p sh2ct2uom8anh6vrbbrxxbkmx554qrx 28250 28249 2014-07-17T08:55:38Z w>Mr. Stradivarius 0 don't set protectionDate to the current time if args.date wasn't specified 28250 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 1rorf7na61ygx9qd4lfgt7kcneymvy9 28251 28250 2014-07-17T12:03:09Z w>Mr. Stradivarius 0 Protection:makeProtectionCategory - return a blank string on no match 28251 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p a93w2pskblq24mad6uey3ij9ang3fkf 28252 28251 2014-07-17T23:33:51Z w>Mr. Stradivarius 0 log keys in Protection:makeProtectionCategory for now, to help with writing the test cases 28252 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') mw.log(key) local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p rbb7ii4a3no28j4ushu9f8gcdqcvio2 28253 28252 2014-07-18T12:55:30Z w>Mr. Stradivarius 0 makeProtectionCategory test cases are finished, so don't log keys any more 28253 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.DISPUTEBLURB = self._makeDisputeBlurbParameter parameterFuncs.DISPUTESECTION = self._makeDisputeSectionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.OFFICEBLURB = self._makeOfficeBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.RESETBLURB = self._makeResetBlurbParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p a93w2pskblq24mad6uey3ij9ang3fkf 28254 28253 2014-07-19T03:45:58Z w>Mr. Stradivarius 0 remove four deprecated parameters from Blurb:_substituteParameters 28254 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the display message key. local key if action == 'edit' and level == 'autoconfirmed' then key = 'edit-request-semi-display' else key = 'edit-request-full-display' end local display = self:_getExpandedMessage(key) -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 3w6059t6nm3w647xdbvaa3pflij7ua4 28255 28254 2014-07-19T03:58:42Z w>Mr. Stradivarius 0 only use one display value for edit requests 28255 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest.exportLinkToLua{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 5kao501hdhbavhnkmej9yfvvb0dj099 28256 28255 2014-07-19T07:15:38Z w>Mr. Stradivarius 0 fix [[Module:Submit an edit request]] function name 28256 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not expiry then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p qr1h7r4a50udkt84ulhbsd1fnube41i 28257 28256 2014-07-19T12:24:03Z w>Mr. Stradivarius 0 add red padlocks when expiry is explicitly set to indefinite 28257 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if type(self._protectionObj.expiry) == 'number' then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local expiry = protectionObj.expiry local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and (not expiry or expiry == 'indef') then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p df21x7f40jhosly0lyy0651cxshvyyr 28258 28257 2014-07-19T12:31:11Z w>Mr. Stradivarius 0 add a Protection:isTemporary method 28258 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p c48eqma1h59t2o0b8amqtaasihrkda9 28259 28258 2014-07-21T23:48:03Z w>Mr. Stradivarius 0 use isDemo instead of args.category and use an isSmall variable while we're at it 28259 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} local isDemo = yesno(args.demo) local isSmall = yesno(args.small) -- Render the banner if protectionObj:isProtected() or isDemo then ret[#ret + 1] = tostring( (isSmall and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if not isDemo then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p d6r0zv75l61crgsmozbqaopv2cdwz5k 28260 28259 2014-07-22T00:52:12Z w>Mr. Stradivarius 0 undo, as a lot of code would need to be changed for template demos to look respectable on unprotected pages 28260 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p c48eqma1h59t2o0b8amqtaasihrkda9 28261 28260 2014-07-22T06:04:03Z w>Mr. Stradivarius 0 add a Blurb:_makeIntroFragmentParameter function to get round the problem of how to deal with commas in run-on sentences using the INTROBLURB parameter 28261 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg return not self.expiry and cfg.expiryCheckActions[self.action] and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p ot62t8js6zg402nx8yy80kikaus40sb 28262 28261 2014-07-22T11:51:38Z w>Mr. Stradivarius 0 make Protection:needsExpiry even more complicated to allow for trinary logic in cfg.expiryCheckActions 28262 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expirycheckactions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p k9a8jjnagnhfk3ozz7ssy755us2bz17 28263 28262 2014-07-22T11:53:16Z w>Mr. Stradivarius 0 fix cfg field name 28263 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat) if cat then return string.format( '[[%s:%s]]', mw.site.namespaces[14].name, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-expiry']) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-incorrect']) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink(msg['tracking-category-template']) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink(cfg.msg['tracking-category-incorrect']) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p iyxbjpbbuw4q4lpcrzx1s2nhaak43wb 28264 28263 2014-07-22T12:48:41Z w>Mr. Stradivarius 0 add category sort keys 28264 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local class = require('Module:Middleclass').class local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = class('Protection') Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection:initialize(args, cfg, title) self._cfg = cfg self.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then self.action = 'edit' elseif self.supportedActions[args.action] then self.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level self.level = effectiveProtectionLevel(self.action, self.title) if self.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. self.level = 'templateeditor' elseif not self.level or (self.action == 'move' and self.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. self.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then self.expiry = 'indef' elseif type(args.expiry) == 'number' then self.expiry = args.expiry else self.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then self.reason = mw.ustring.lower(args[1]) if self.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then self.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do self.bannerConfig = {} local configTables = {} if cfg.banners[self.action] then configTables[#configTables + 1] = cfg.banners[self.action][self.reason] end if cfg.defaultBanners[self.action] then configTables[#configTables + 1] = cfg.defaultBanners[self.action][self.level] configTables[#configTables + 1] = cfg.defaultBanners[self.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(self.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then self.bannerConfig[field] = t[field] break end end end end end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = class('Blurb') Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb:initialize(protectionObj, args, cfg) self._cfg = cfg self._protectionObj = protectionObj self._args = args end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = class('BannerTemplate') function BannerTemplate:initialize(protectionObj, cfg) self._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then self._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. self._imageFilename = self._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = self._cfg.images if images[action] then if images[action][level] then self._imageFilename = images[action][level] elseif images[action].default then self._imageFilename = images[action].default end end end end end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = BannerTemplate:subclass('Banner') function Banner:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(40) self:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. self._reasonText = blurbObj:makeBannerText('text') self._explanationText = blurbObj:makeBannerText('explanation') self._page = protectionObj.title.prefixedText -- Only makes a difference in testing. end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = BannerTemplate:subclass('Padlock') function Padlock:initialize(protectionObj, blurbObj, cfg) BannerTemplate.initialize(self, protectionObj, cfg) -- This doesn't need the blurb. self:setImageWidth(20) self:setImageTooltip(blurbObj:makeBannerText('tooltip')) self._imageAlt = blurbObj:makeBannerText('alt') self._imageLink = blurbObj:makeBannerText('link') self._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, Protection, -- equivalent to Protection:new() args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end -- Initialise the blurb object local blurbObj = Blurb:new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) :new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p lwv9hk6vq55p407s2q9s8bo8g2kx4l6 28265 28264 2014-07-22T17:48:12Z w>Jackmcbarn 0 don't use Module:Middleclass 28265 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(obj.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = Banner.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 1z02phlgd31ttvfjr8j3dodussm2k6d 28266 28265 2014-07-22T17:53:51Z w>Jackmcbarn 0 fix a few mistakes 28266 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace -- Deal with special cases first. if (namespace == 10 or namespace == 828) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 8w8tp7tm3t1mo3azlfeq2bkdulyttob 28267 28266 2014-07-23T01:48:59Z w>Mr. Stradivarius 0 allow the template reason to show the red padlock in any namespace 28267 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.imageIndefReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 53pe9k9drix5cmnm8gyzbgavu7jso73 28268 28267 2014-07-23T02:46:45Z w>Mr. Stradivarius 0 fix cfg table name 28268 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 4wc4yw9jtdp9gn2wvx5k2a9q213ewei 28269 28268 2014-08-05T17:17:50Z w>Mr. Stradivarius 0 Protected Module:Protection banner: [[WP:High-risk templates|High-risk Lua module]] ([Edit=Allow only template editors and admins] (indefinite) [Move=Allow only template editors and admins] (indefinite)) 28268 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require('Module:Protection banner/config') local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p 4wc4yw9jtdp9gn2wvx5k2a9q213ewei 28270 28269 2014-08-08T14:20:10Z w>Mr. Stradivarius 0 add a "TOOLTIPFRAGMENT" parameter, as we were having the same issues with commas in tooltips as we did with INTROBLURB and INTROFRAGMENT; also move the config module name to a global variable so that it's more obvious when updating 28270 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) getArgs = getArgs or require('Module:Arguments').getArgs cfg = cfg or require(CONFIG_MODULE) local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} local args = getArgs(frame, {parentOnly = defaultArgs and true}) for k, v in pairs(defaultArgs) do args[k] = v end return p._main(args, cfg) end return p qrswv8ug8v5bwx8d4xdewkts8e0d06y 28271 28270 2014-08-10T17:25:15Z w>Mr. Stradivarius 0 allow user-specified args to overwrite default args; updated from sandbox 28271 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require('Module:Protection banner/config') -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) local ret = {} -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parentTitle = frame:getParent():getTitle() parentTitle = parentTitle:gsub('/sandbox$', '') local defaultArgs = cfg.wrappers[parentTitle] or {} -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p o46d6qlaz9x0ki21bc00k18o251v06g 28272 28271 2014-09-06T21:14:04Z w>Jackmcbarn 0 only show banners for actions other than edit if they're more restricted than edit 28272 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 0) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 0) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 0) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey )) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined') end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default') end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) )) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set') local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) -- Initialise the protection object and check for errors local protectionObjCreated, protectionObj = pcall( Protection.new, args, cfg, title ) if not protectionObjCreated then local errorBlurb = cfg.msg['error-message-blurb'] or 'Error: $1.' local errorText = mw.message.newRawMessage(errorBlurb) :params(protectionObj) -- protectionObj is the error message :plain() return string.format( '<strong class="error">%s</strong>%s', errorText, makeCategoryLink( cfg.msg['tracking-category-incorrect'], title and title.text or mw.title.getCurrentTitle().text ) ) end local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] or {} -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p 3rt907i01lot202xsr2tp4x7mujiw0s 28273 28272 2014-10-03T03:20:45Z w>Jackmcbarn 0 use actual Lua errors, and a small fix to parameter handling 28273 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p ba3zpfxibpg20582pqwh60djxr9z9vq 28274 28273 2014-10-14T21:48:57Z w>Mr. Stradivarius 0 add support for the "demolevel" parameter; code by myself and [[User:Jackmcbarn]] 28274 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local newFileLink = require('Module:File link').new local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return newFileLink(filename) :width(self._imageWidth or 20) :alt(self._imageAlt) :link(self._imageLink) :caption(self._imageCaption) :render() end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p tv5rch13lvy83akgh9r9h6ett6g720t 28275 28274 2014-12-18T12:30:34Z w>Mr. Stradivarius 0 transitioning to new version of [[Module:File link]] - will switch from the sandbox to the main module in a short while 28275 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link/sandbox')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p p6sxw0g00zt8jlnv3dkbjvykg9t5djm 28276 28275 2014-12-18T12:33:04Z w>Mr. Stradivarius 0 use [[Module:File link]] again, instead of the sandbox 28276 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if obj.level == 'accountcreator' then -- Lump titleblacklisted pages in with template-protected pages, -- since templateeditors can do both. obj.level = 'templateeditor' elseif not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p re37ycozek1bayrzrtu3otogs1mpwxk 28277 28276 2015-01-06T22:20:10Z w>Jackmcbarn 0 accountcreator level is gone 28277 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p ftb9ninr5wguj33vszyec49fjcv1kwv 28278 28277 2015-03-23T13:52:36Z w>Mr. Stradivarius 0 switch to using [[mw:Help:Page status indicators|page status indicators]] for the padlock icons (will switch from the config sandbox in a second) 28278 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config/sandbox' -- *** SWITCH THIS BACK BEFORE UPDATING THE MAIN MODULE *** -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() return mw.getCurrentFrame():extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p e8a1nxsyky8btb91cigmvdwjcw48h96 28279 28278 2015-03-23T13:53:23Z w>Mr. Stradivarius 0 switch back to the main config module 28279 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() return mw.getCurrentFrame():extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p 8kojit8ioxn5snpz1fxelab24eo37gr 28280 28279 2015-03-23T14:02:19Z w>Mr. Stradivarius 0 undo for now - the code looks good, but we will need to change everything over at the same time to avoid it looking like a giant mess 28280 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p ftb9ninr5wguj33vszyec49fjcv1kwv 28281 28280 2015-03-26T18:22:18Z w>Edokter 0 Redo switch to <indicator> in concert with {{top icon}} 28281 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() return mw.getCurrentFrame():extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p 8kojit8ioxn5snpz1fxelab24eo37gr 28282 28281 2015-03-26T18:24:08Z w>Edokter 0 Undid revision 653638001 by [[Special:Contributions/Edokter|Edokter]] ([[User talk:Edokter|talk]]) Getting weird error! 28282 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._right = cfg.padlockPositions[protectionObj.action] or cfg.padlockPositions.default or '55px' return setmetatable(obj, Padlock) end function Padlock:__tostring() local root = mw.html.create('div') root :addClass('metadata topicon nopopups') :attr('id', 'protected-icon') :css{display = 'none', right = self._right} :wikitext(self:renderImage()) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p ftb9ninr5wguj33vszyec49fjcv1kwv 28283 28282 2015-03-27T00:07:11Z w>Mr. Stradivarius 0 switch to <indicator> tags again - the previous error was because the config module needs to be updated at the same time 28283 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() return mw.getCurrentFrame():extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p 8kojit8ioxn5snpz1fxelab24eo37gr 28284 28283 2015-03-27T04:43:25Z w>Mr. Stradivarius 0 add hack to prevent indicator tags producing whitespace at the top of articles 28284 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. local nowiki = frame:extensionTag{name = 'nowiki'} local indicator = frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } return nowiki .. indicator end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p st3m6w0zczh9ow7169k5imish4jj6qm 28285 28284 2015-09-11T20:30:43Z w>Ymblanter 0 Changed protection level of Module:Protection banner: [[WP:High-risk templates|High-risk Lua module]]: RFPP request ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)) 28284 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry if args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. local nowiki = frame:extensionTag{name = 'nowiki'} local indicator = frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } return nowiki .. indicator end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p st3m6w0zczh9ow7169k5imish4jj6qm 28286 28285 2015-12-11T17:14:31Z w>Cenarium 0 add expiry automatically for actions other than 'autoreview' using new {{PROTECTIONEXPIRY:action}} magic word implemented through [[Module:Effective protection expiry]] 28286 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') elseif args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. local nowiki = frame:extensionTag{name = 'nowiki'} local indicator = frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } return nowiki .. indicator end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its protection from some other action, -- then don't bother displaying anything for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy(cfg.hierarchy, protectionObj.level)[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p 4a8nu5ej1ue3xs76jec9oyyd854bwa3 28287 28286 2016-03-03T13:11:32Z w>Mr. Stradivarius 0 add support for upload protection, and make some formatting tweaks 28287 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') elseif args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. local nowiki = frame:extensionTag{name = 'nowiki'} local indicator = frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } return nowiki .. indicator end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p slrmrbbswex243d342o7ux4dwfl6ev8 28288 28287 2016-07-06T05:53:36Z w>Ymblanter 0 Changed protection level of Module:Protection banner: [[WP:High-risk templates|High-risk Lua module]]: request at my talk page ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite)) 28287 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) local nsText = mw.site.namespaces[14].name if cat and sort then return string.format( '[[%s:%s|%s]]', nsText, cat, sort ) elseif cat then return string.format( '[[%s:%s]]', nsText, cat ) else return '' end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) lang = lang or mw.language.getContentLanguage() local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s ("%s")', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end local function toTableEnd(t, pos) -- Sends the value at position pos to the end of array t, and shifts the -- other items down accordingly. return table.insert(t, table.remove(t, pos)) end local function walkHierarchy(hierarchy, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then break end toWalk[k] = nil retval[k] = true for _,v in ipairs(hierarchy[k]) do if not retval[v] then toWalk[v] = true end end end return retval end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action ("%s")', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') elseif args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment do namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] if self.reason and cfg.reasonsWithNamespacePriority[self.reason] then -- table.insert(order, 3, table.remove(order, 2)) toTableEnd(order, 2) else toTableEnd(order, 3) end --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:setImageWidth(width) self._imageWidth = width end function BannerTemplate:setImageTooltip(tooltip) self._imageCaption = tooltip end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self._imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self._imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(40) obj:setImageTooltip(blurbObj:makeBannerText('alt')) -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj:setImageWidth(20) obj:setImageTooltip(blurbObj:makeBannerText('tooltip')) obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. local nowiki = frame:extensionTag{name = 'nowiki'} local indicator = frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } return nowiki .. indicator end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not walkHierarchy( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p slrmrbbswex243d342o7ux4dwfl6ev8 28289 28288 2016-08-04T01:55:19Z w>Jackmcbarn 0 bring changes from sandbox live 28289 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') elseif args.expiry then if cfg.indefStrings[args.expiry] then obj.expiry = 'indef' elseif type(args.expiry) == 'number' then obj.expiry = args.expiry else obj.expiry = validateDate(args.expiry, 'expiry date') end end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:needsExpiry() local cfg = self._cfg local actionNeedsCheck = cfg.expiryCheckActions[self.action] return not self.expiry and ( actionNeedsCheck or ( actionNeedsCheck == nil and self.reason -- the old {{pp-protected}} didn't check for expiry and not cfg.reasonsWithoutExpiryCheck[self.reason] ) ) end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:needsExpiry() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-expiry'], self.title.text ) end if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p 2xr148t8gwxs5lnye7r54qmsmn4uwpd 28290 28289 2016-09-29T18:32:41Z w>Cenarium 0 remove expiry param (now also automatically retrieved for autoreview) and needsexpiry check 28290 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p ice162y8kua930ie41kredxjaxhzy3y 28291 28290 2017-06-23T21:55:23Z w>MarcoAurelio 0 Protected "[[Module:Protection banner]]": High-risk Lua module ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)) 28290 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p ice162y8kua930ie41kredxjaxhzy3y 28292 28291 2020-04-01T06:12:46Z w>MusikAnimal 0 1 revision imported 28290 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isProtected() return self.level ~= '*' end function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() local cfg = self._cfg local title = self.title -- Exit if the page is not protected. if not self:isProtected() then return '' end -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:isProtected() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = { self:makeProtectionCategory() } if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:isProtected() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p ice162y8kua930ie41kredxjaxhzy3y 28293 28292 2020-09-19T13:06:07Z w>Mr. Stradivarius 0 don't add protection categories or show padlock icons for user js/css pages; based on code contributed by [[User:ProcrastinatingReader]] 28293 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return require('Module:Vandal-m')._main{ self._args.user or self._protectionObj.title.baseText } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p pwlommmk9wzkviwu5fu6f8b29n12m1l 28294 28293 2021-03-23T19:27:30Z w>Pppery 0 Replace [[Module:Vandal-m]] per TfD; getting this over-two-year-old merge proposal finally completed 28294 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return mw.getCurrentFrame():expandTemplate{ title="vandal-m", args={self._args.user or self._protectionObj.title.baseText} } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)] then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p egb9lvnecry89avp7csr2y1n561gask 28295 28294 2021-07-16T11:59:29Z w>ProcrastinatingReader 0 add catonly param which hides both the banner and padlock if set to yes. all testcases pass. tested in sandbox. 28295 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('Module:No globals') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return mw.getCurrentFrame():expandTemplate{ title="vandal-m", args={self._args.user or self._protectionObj.title.baseText} } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if not yesno(args.catonly) and (protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)]) then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p ktral6mmlw9hhlxwgaq85237qklrdx8 28296 28295 2022-10-21T08:07:11Z w>WOSlinker 0 use require('strict') instead of require('Module:No globals') 28296 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('strict') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return mw.getCurrentFrame():expandTemplate{ title="vandal-m", args={self._args.user or self._protectionObj.title.baseText} } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if not yesno(args.catonly) and (protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)]) then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p g1esh5v0eq6i86pqpylkdm09loryn3e 28297 28296 2025-01-23T10:28:19Z w>SilverLocust 0 Flagging [[WP:PIA]] pages for arbitration enforcement via [[Special:AbuseFilter/1339]] 28297 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('strict') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return mw.getCurrentFrame():expandTemplate{ title="vandal-m", args={self._args.user or self._protectionObj.title.baseText} } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if not yesno(args.catonly) and (protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)]) then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end -- For arbitration enforcement, flagging [[WP:PIA]] pages to enable [[Special:AbuseFilter/1339]] to flag edits to them if protectionObj.level == "extendedconfirmed" then if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then ret[#ret + 1] = "<p class='PIA-flag' style='display:none; visibility:hidden;'>This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.</p>" end end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p jphhqx47xtxwee24lw6gf0dc67scweu 28298 28297 2025-03-19T17:58:54Z w>SilverLocust 0 fix for mobile and search issue, see talk page 28298 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('strict') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return mw.getCurrentFrame():expandTemplate{ title="vandal-m", args={self._args.user or self._protectionObj.title.baseText} } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if not yesno(args.catonly) and (protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)]) then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end -- For arbitration enforcement, flagging [[WP:PIA]] pages to enable [[Special:AbuseFilter/1339]] to flag edits to them if protectionObj.level == "extendedconfirmed" then if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then ret[#ret + 1] = "<p class='PIA-flag' style='display:none; visibility:hidden;' title='This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.'></p>" end end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p 2lyr6ebd580cvha7qta16zrremxkzxz 28299 28298 2025-12-30T02:00:36Z en>Codename Noreste 0 240 revisions imported from [[:w:Module:Protection_banner]]: Required for [[Module:Documentation]]. 28298 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('strict') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'extendedconfirmed' then requestType = 'extended' elseif level == 'templateeditor' then requestType = 'template' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return mw.getCurrentFrame():expandTemplate{ title="vandal-m", args={self._args.user or self._protectionObj.title.baseText} } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if not yesno(args.catonly) and (protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)]) then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end -- For arbitration enforcement, flagging [[WP:PIA]] pages to enable [[Special:AbuseFilter/1339]] to flag edits to them if protectionObj.level == "extendedconfirmed" then if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then ret[#ret + 1] = "<p class='PIA-flag' style='display:none; visibility:hidden;' title='This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.'></p>" end end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p 2lyr6ebd580cvha7qta16zrremxkzxz 28300 28299 2026-01-22T19:03:34Z en>Codename Noreste 0 Including autopatroller protection too. 28300 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('strict') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'autopatrolled' then requestType = 'autopatrol' elseif level == 'patroller' then requestType = 'autopatrol' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return mw.getCurrentFrame():expandTemplate{ title="vandal-m", args={self._args.user or self._protectionObj.title.baseText} } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if not yesno(args.catonly) and (protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)]) then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end -- For arbitration enforcement, flagging [[WP:PIA]] pages to enable [[Special:AbuseFilter/1339]] to flag edits to them if protectionObj.level == "extendedconfirmed" then if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then ret[#ret + 1] = "<p class='PIA-flag' style='display:none; visibility:hidden;' title='This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.'></p>" end end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p kofqd7ht22vtk3ct36p0fbw3dizvwut 28301 28300 2026-10-24T01:16:03Z Kiran Gopi 624 [[:en:Module:Protection_banner]] എന്നതിൽ നിന്ന് 242 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28300 Scribunto text/plain -- This module implements {{pp-meta}} and its daughter templates such as -- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}. -- Initialise necessary modules. require('strict') local makeFileLink = require('Module:File link')._main local effectiveProtectionLevel = require('Module:Effective protection level')._main local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main local yesno = require('Module:Yesno') -- Lazily initialise modules and objects we don't always need. local getArgs, makeMessageBox, lang -- Set constants. local CONFIG_MODULE = 'Module:Protection banner/config' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function makeCategoryLink(cat, sort) if cat then return string.format( '[[%s:%s|%s]]', mw.site.namespaces[14].name, cat, sort ) end end -- Validation function for the expiry and the protection date local function validateDate(dateString, dateType) if not lang then lang = mw.language.getContentLanguage() end local success, result = pcall(lang.formatDate, lang, 'U', dateString) if success then result = tonumber(result) if result then return result end end error(string.format( 'invalid %s: %s', dateType, tostring(dateString) ), 4) end local function makeFullUrl(page, query, display) return string.format( '[%s %s]', tostring(mw.uri.fullUrl(page, query)), display ) end -- Given a directed graph formatted as node -> table of direct successors, -- get a table of all nodes reachable from a given node (though always -- including the given node). local function getReachableNodes(graph, start) local toWalk, retval = {[start] = true}, {} while true do -- Can't use pairs() since we're adding and removing things as we're iterating local k = next(toWalk) -- This always gets the "first" key if k == nil then return retval end toWalk[k] = nil retval[k] = true for _,v in ipairs(graph[k]) do if not retval[v] then toWalk[v] = true end end end end -------------------------------------------------------------------------------- -- Protection class -------------------------------------------------------------------------------- local Protection = {} Protection.__index = Protection Protection.supportedActions = { edit = true, move = true, autoreview = true, upload = true } Protection.bannerConfigFields = { 'text', 'explanation', 'tooltip', 'alt', 'link', 'image' } function Protection.new(args, cfg, title) local obj = {} obj._cfg = cfg obj.title = title or mw.title.getCurrentTitle() -- Set action if not args.action then obj.action = 'edit' elseif Protection.supportedActions[args.action] then obj.action = args.action else error(string.format( 'invalid action: %s', tostring(args.action) ), 3) end -- Set level obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title) if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then -- Users need to be autoconfirmed to move pages anyway, so treat -- semi-move-protected pages as unprotected. obj.level = '*' end -- Set expiry local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title) if effectiveExpiry == 'infinity' then obj.expiry = 'indef' elseif effectiveExpiry ~= 'unknown' then obj.expiry = validateDate(effectiveExpiry, 'expiry date') end -- Set reason if args[1] then obj.reason = mw.ustring.lower(args[1]) if obj.reason:find('|') then error('reasons cannot contain the pipe character ("|")', 3) end end -- Set protection date if args.date then obj.protectionDate = validateDate(args.date, 'protection date') end -- Set banner config do obj.bannerConfig = {} local configTables = {} if cfg.banners[obj.action] then configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason] end if cfg.defaultBanners[obj.action] then configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level] configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default end configTables[#configTables + 1] = cfg.masterBanner for i, field in ipairs(Protection.bannerConfigFields) do for j, t in ipairs(configTables) do if t[field] then obj.bannerConfig[field] = t[field] break end end end end return setmetatable(obj, Protection) end function Protection:isUserScript() -- Whether the page is a user JavaScript or CSS page. local title = self.title return title.namespace == 2 and ( title.contentModel == 'javascript' or title.contentModel == 'css' ) end function Protection:isProtected() return self.level ~= '*' end function Protection:shouldShowLock() -- Whether we should output a banner/padlock return self:isProtected() and not self:isUserScript() end -- Whether this page needs a protection category. Protection.shouldHaveProtectionCategory = Protection.shouldShowLock function Protection:isTemporary() return type(self.expiry) == 'number' end function Protection:makeProtectionCategory() if not self:shouldHaveProtectionCategory() then return '' end local cfg = self._cfg local title = self.title -- Get the expiry key fragment. local expiryFragment if self.expiry == 'indef' then expiryFragment = self.expiry elseif type(self.expiry) == 'number' then expiryFragment = 'temp' end -- Get the namespace key fragment. local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace] if not namespaceFragment and title.namespace % 2 == 1 then namespaceFragment = 'talk' end -- Define the order that key fragments are tested in. This is done with an -- array of tables containing the value to be tested, along with its -- position in the cfg.protectionCategories table. local order = { {val = expiryFragment, keypos = 1}, {val = namespaceFragment, keypos = 2}, {val = self.reason, keypos = 3}, {val = self.level, keypos = 4}, {val = self.action, keypos = 5} } --[[ -- The old protection templates used an ad-hoc protection category system, -- with some templates prioritising namespaces in their categories, and -- others prioritising the protection reason. To emulate this in this module -- we use the config table cfg.reasonsWithNamespacePriority to set the -- reasons for which namespaces have priority over protection reason. -- If we are dealing with one of those reasons, move the namespace table to -- the end of the order table, i.e. give it highest priority. If not, the -- reason should have highest priority, so move that to the end of the table -- instead. --]] table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3)) --[[ -- Define the attempt order. Inactive subtables (subtables with nil "value" -- fields) are moved to the end, where they will later be given the key -- "all". This is to cut down on the number of table lookups in -- cfg.protectionCategories, which grows exponentially with the number of -- non-nil keys. We keep track of the number of active subtables with the -- noActive parameter. --]] local noActive, attemptOrder do local active, inactive = {}, {} for i, t in ipairs(order) do if t.val then active[#active + 1] = t else inactive[#inactive + 1] = t end end noActive = #active attemptOrder = active for i, t in ipairs(inactive) do attemptOrder[#attemptOrder + 1] = t end end --[[ -- Check increasingly generic key combinations until we find a match. If a -- specific category exists for the combination of key fragments we are -- given, that match will be found first. If not, we keep trying different -- key fragment combinations until we match using the key -- "all-all-all-all-all". -- -- To generate the keys, we index the key subtables using a binary matrix -- with indexes i and j. j is only calculated up to the number of active -- subtables. For example, if there were three active subtables, the matrix -- would look like this, with 0 corresponding to the key fragment "all", and -- 1 corresponding to other key fragments. -- -- j 1 2 3 -- i -- 1 1 1 1 -- 2 0 1 1 -- 3 1 0 1 -- 4 0 0 1 -- 5 1 1 0 -- 6 0 1 0 -- 7 1 0 0 -- 8 0 0 0 -- -- Values of j higher than the number of active subtables are set -- to the string "all". -- -- A key for cfg.protectionCategories is constructed for each value of i. -- The position of the value in the key is determined by the keypos field in -- each subtable. --]] local cats = cfg.protectionCategories for i = 1, 2^noActive do local key = {} for j, t in ipairs(attemptOrder) do if j > noActive then key[t.keypos] = 'all' else local quotient = i / 2 ^ (j - 1) quotient = math.ceil(quotient) if quotient % 2 == 1 then key[t.keypos] = t.val else key[t.keypos] = 'all' end end end key = table.concat(key, '|') local attempt = cats[key] if attempt then return makeCategoryLink(attempt, title.text) end end return '' end function Protection:isIncorrect() local expiry = self.expiry return not self:shouldHaveProtectionCategory() or type(expiry) == 'number' and expiry < os.time() end function Protection:isTemplateProtectedNonTemplate() local action, namespace = self.action, self.title.namespace return self.level == 'templateeditor' and ( (action ~= 'edit' and action ~= 'move') or (namespace ~= 10 and namespace ~= 828) ) end function Protection:makeCategoryLinks() local msg = self._cfg.msg local ret = {self:makeProtectionCategory()} if self:isIncorrect() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-incorrect'], self.title.text ) end if self:isTemplateProtectedNonTemplate() then ret[#ret + 1] = makeCategoryLink( msg['tracking-category-template'], self.title.text ) end return table.concat(ret) end -------------------------------------------------------------------------------- -- Blurb class -------------------------------------------------------------------------------- local Blurb = {} Blurb.__index = Blurb Blurb.bannerTextFields = { text = true, explanation = true, tooltip = true, alt = true, link = true } function Blurb.new(protectionObj, args, cfg) return setmetatable({ _cfg = cfg, _protectionObj = protectionObj, _args = args }, Blurb) end -- Private methods -- function Blurb:_formatDate(num) -- Formats a Unix timestamp into dd Month, YYYY format. lang = lang or mw.language.getContentLanguage() local success, date = pcall( lang.formatDate, lang, self._cfg.msg['expiry-date-format'] or 'j F Y', '@' .. tostring(num) ) if success then return date end end function Blurb:_getExpandedMessage(msgKey) return self:_substituteParameters(self._cfg.msg[msgKey]) end function Blurb:_substituteParameters(msg) if not self._params then local parameterFuncs = {} parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter parameterFuncs.EDITREQUEST = self._makeEditRequestParameter parameterFuncs.EXPIRY = self._makeExpiryParameter parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter parameterFuncs.IMAGELINK = self._makeImageLinkParameter parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter parameterFuncs.PAGETYPE = self._makePagetypeParameter parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter parameterFuncs.TALKPAGE = self._makeTalkPageParameter parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter parameterFuncs.VANDAL = self._makeVandalTemplateParameter self._params = setmetatable({}, { __index = function (t, k) local param if parameterFuncs[k] then param = parameterFuncs[k](self) end param = param or '' t[k] = param return param end }) end msg = msg:gsub('${(%u+)}', self._params) return msg end function Blurb:_makeCurrentVersionParameter() -- A link to the page history or the move log, depending on the kind of -- protection. local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'move' then -- We need the move log link. return makeFullUrl( 'Special:Log', {type = 'move', page = pagename}, self:_getExpandedMessage('current-version-move-display') ) else -- We need the history link. return makeFullUrl( pagename, {action = 'history'}, self:_getExpandedMessage('current-version-edit-display') ) end end function Blurb:_makeEditRequestParameter() local mEditRequest = require('Module:Submit an edit request') local action = self._protectionObj.action local level = self._protectionObj.level -- Get the edit request type. local requestType if action == 'edit' then if level == 'autoconfirmed' then requestType = 'semi' elseif level == 'autopatrolled' then requestType = 'autopatrol' elseif level == 'patroller' then requestType = 'autopatrol' end end requestType = requestType or 'full' -- Get the display value. local display = self:_getExpandedMessage('edit-request-display') return mEditRequest._link{type = requestType, display = display} end function Blurb:_makeExpiryParameter() local expiry = self._protectionObj.expiry if type(expiry) == 'number' then return self:_formatDate(expiry) else return expiry end end function Blurb:_makeExplanationBlurbParameter() -- Cover special cases first. if self._protectionObj.title.namespace == 8 then -- MediaWiki namespace return self:_getExpandedMessage('explanation-blurb-nounprotect') end -- Get explanation blurb table keys local action = self._protectionObj.action local level = self._protectionObj.level local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject' -- Find the message in the explanation blurb table and substitute any -- parameters. local explanations = self._cfg.explanationBlurbs local msg if explanations[action][level] and explanations[action][level][talkKey] then msg = explanations[action][level][talkKey] elseif explanations[action][level] and explanations[action][level].default then msg = explanations[action][level].default elseif explanations[action].default and explanations[action].default[talkKey] then msg = explanations[action].default[talkKey] elseif explanations[action].default and explanations[action].default.default then msg = explanations[action].default.default else error(string.format( 'could not find explanation blurb for action "%s", level "%s" and talk key "%s"', action, level, talkKey ), 8) end return self:_substituteParameters(msg) end function Blurb:_makeImageLinkParameter() local imageLinks = self._cfg.imageLinks local action = self._protectionObj.action local level = self._protectionObj.level local msg if imageLinks[action][level] then msg = imageLinks[action][level] elseif imageLinks[action].default then msg = imageLinks[action].default else msg = imageLinks.edit.default end return self:_substituteParameters(msg) end function Blurb:_makeIntroBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-blurb-expiry') else return self:_getExpandedMessage('intro-blurb-noexpiry') end end function Blurb:_makeIntroFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('intro-fragment-expiry') else return self:_getExpandedMessage('intro-fragment-noexpiry') end end function Blurb:_makePagetypeParameter() local pagetypes = self._cfg.pagetypes return pagetypes[self._protectionObj.title.namespace] or pagetypes.default or error('no default pagetype defined', 8) end function Blurb:_makeProtectionBlurbParameter() local protectionBlurbs = self._cfg.protectionBlurbs local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionBlurbs[action][level] then msg = protectionBlurbs[action][level] elseif protectionBlurbs[action].default then msg = protectionBlurbs[action].default elseif protectionBlurbs.edit.default then msg = protectionBlurbs.edit.default else error('no protection blurb defined for protectionBlurbs.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionDateParameter() local protectionDate = self._protectionObj.protectionDate if type(protectionDate) == 'number' then return self:_formatDate(protectionDate) else return protectionDate end end function Blurb:_makeProtectionLevelParameter() local protectionLevels = self._cfg.protectionLevels local action = self._protectionObj.action local level = self._protectionObj.level local msg if protectionLevels[action][level] then msg = protectionLevels[action][level] elseif protectionLevels[action].default then msg = protectionLevels[action].default elseif protectionLevels.edit.default then msg = protectionLevels.edit.default else error('no protection level defined for protectionLevels.edit.default', 8) end return self:_substituteParameters(msg) end function Blurb:_makeProtectionLogParameter() local pagename = self._protectionObj.title.prefixedText if self._protectionObj.action == 'autoreview' then -- We need the pending changes log. return makeFullUrl( 'Special:Log', {type = 'stable', page = pagename}, self:_getExpandedMessage('pc-log-display') ) else -- We need the protection log. return makeFullUrl( 'Special:Log', {type = 'protect', page = pagename}, self:_getExpandedMessage('protection-log-display') ) end end function Blurb:_makeTalkPageParameter() return string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[self._protectionObj.title.namespace].talk.name, self._protectionObj.title.text, self._args.section or 'top', self:_getExpandedMessage('talk-page-link-display') ) end function Blurb:_makeTooltipBlurbParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-blurb-expiry') else return self:_getExpandedMessage('tooltip-blurb-noexpiry') end end function Blurb:_makeTooltipFragmentParameter() if self._protectionObj:isTemporary() then return self:_getExpandedMessage('tooltip-fragment-expiry') else return self:_getExpandedMessage('tooltip-fragment-noexpiry') end end function Blurb:_makeVandalTemplateParameter() return mw.getCurrentFrame():expandTemplate{ title="vandal-m", args={self._args.user or self._protectionObj.title.baseText} } end -- Public methods -- function Blurb:makeBannerText(key) -- Validate input. if not key or not Blurb.bannerTextFields[key] then error(string.format( '"%s" is not a valid banner config field', tostring(key) ), 2) end -- Generate the text. local msg = self._protectionObj.bannerConfig[key] if type(msg) == 'string' then return self:_substituteParameters(msg) elseif type(msg) == 'function' then msg = msg(self._protectionObj, self._args) if type(msg) ~= 'string' then error(string.format( 'bad output from banner config function with key "%s"' .. ' (expected string, got %s)', tostring(key), type(msg) ), 4) end return self:_substituteParameters(msg) end end -------------------------------------------------------------------------------- -- BannerTemplate class -------------------------------------------------------------------------------- local BannerTemplate = {} BannerTemplate.__index = BannerTemplate function BannerTemplate.new(protectionObj, cfg) local obj = {} obj._cfg = cfg -- Set the image filename. local imageFilename = protectionObj.bannerConfig.image if imageFilename then obj._imageFilename = imageFilename else -- If an image filename isn't specified explicitly in the banner config, -- generate it from the protection status and the namespace. local action = protectionObj.action local level = protectionObj.level local namespace = protectionObj.title.namespace local reason = protectionObj.reason -- Deal with special cases first. if ( namespace == 10 or namespace == 828 or reason and obj._cfg.indefImageReasons[reason] ) and action == 'edit' and level == 'sysop' and not protectionObj:isTemporary() then -- Fully protected modules and templates get the special red "indef" -- padlock. obj._imageFilename = obj._cfg.msg['image-filename-indef'] else -- Deal with regular protection types. local images = obj._cfg.images if images[action] then if images[action][level] then obj._imageFilename = images[action][level] elseif images[action].default then obj._imageFilename = images[action].default end end end end return setmetatable(obj, BannerTemplate) end function BannerTemplate:renderImage() local filename = self._imageFilename or self._cfg.msg['image-filename-default'] or 'Transparent.gif' return makeFileLink{ file = filename, size = (self.imageWidth or 20) .. 'px', alt = self._imageAlt, link = self._imageLink, caption = self.imageCaption } end -------------------------------------------------------------------------------- -- Banner class -------------------------------------------------------------------------------- local Banner = setmetatable({}, BannerTemplate) Banner.__index = Banner function Banner.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 40 obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip. obj._reasonText = blurbObj:makeBannerText('text') obj._explanationText = blurbObj:makeBannerText('explanation') obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing. return setmetatable(obj, Banner) end function Banner:__tostring() -- Renders the banner. makeMessageBox = makeMessageBox or require('Module:Message box').main local reasonText = self._reasonText or error('no reason text set', 2) local explanationText = self._explanationText local mbargs = { page = self._page, type = 'protection', image = self:renderImage(), text = string.format( "'''%s'''%s", reasonText, explanationText and '<br />' .. explanationText or '' ) } return makeMessageBox('mbox', mbargs) end -------------------------------------------------------------------------------- -- Padlock class -------------------------------------------------------------------------------- local Padlock = setmetatable({}, BannerTemplate) Padlock.__index = Padlock function Padlock.new(protectionObj, blurbObj, cfg) local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb. obj.imageWidth = 20 obj.imageCaption = blurbObj:makeBannerText('tooltip') obj._imageAlt = blurbObj:makeBannerText('alt') obj._imageLink = blurbObj:makeBannerText('link') obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action] or cfg.padlockIndicatorNames.default or 'pp-default' return setmetatable(obj, Padlock) end function Padlock:__tostring() local frame = mw.getCurrentFrame() -- The nowiki tag helps prevent whitespace at the top of articles. return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{ name = 'indicator', args = {name = self._indicatorName}, content = self:renderImage() } end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- This is used for testing purposes. return { Protection = Protection, Blurb = Blurb, BannerTemplate = BannerTemplate, Banner = Banner, Padlock = Padlock, } end function p._main(args, cfg, title) args = args or {} cfg = cfg or require(CONFIG_MODULE) local protectionObj = Protection.new(args, cfg, title) local ret = {} -- If a page's edit protection is equally or more restrictive than its -- protection from some other action, then don't bother displaying anything -- for the other action (except categories). if not yesno(args.catonly) and (protectionObj.action == 'edit' or args.demolevel or not getReachableNodes( cfg.hierarchy, protectionObj.level )[effectiveProtectionLevel('edit', protectionObj.title)]) then -- Initialise the blurb object local blurbObj = Blurb.new(protectionObj, args, cfg) -- Render the banner if protectionObj:shouldShowLock() then ret[#ret + 1] = tostring( (yesno(args.small) and Padlock or Banner) .new(protectionObj, blurbObj, cfg) ) end end -- Render the categories if yesno(args.category) ~= false then ret[#ret + 1] = protectionObj:makeCategoryLinks() end -- For arbitration enforcement, flagging [[WP:PIA]] pages to enable [[Special:AbuseFilter/1339]] to flag edits to them if protectionObj.level == "extendedconfirmed" then if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then ret[#ret + 1] = "<p class='PIA-flag' style='display:none; visibility:hidden;' title='This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.'></p>" end end return table.concat(ret) end function p.main(frame, cfg) cfg = cfg or require(CONFIG_MODULE) -- Find default args, if any. local parent = frame.getParent and frame:getParent() local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')] -- Find user args, and use the parent frame if we are being called from a -- wrapper template. getArgs = getArgs or require('Module:Arguments').getArgs local userArgs = getArgs(frame, { parentOnly = defaultArgs, frameOnly = not defaultArgs }) -- Build the args table. User-specified args overwrite default args. local args = {} for k, v in pairs(defaultArgs or {}) do args[k] = v end for k, v in pairs(userArgs) do args[k] = v end return p._main(args, cfg) end return p kofqd7ht22vtk3ct36p0fbw3dizvwut ഘടകം:Protection banner/config 828 7375 28302 2014-06-06T14:07:22Z w>Mr. Stradivarius 0 move config from [[Module:Protection banner]] 28302 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } return cfg 4virbbsn7tbppzo9901r8n9fucesy5a 28303 28302 2014-06-08T15:02:05Z w>Mr. Stradivarius 0 add default banners and images 28303 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners = { -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement edit = { blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', }, dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', }, office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', }, reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', }, sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', }, usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', }, vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } }, move = { dispute = { }, vandalism = { }, move = { } }, create = { }, autoreview = { pc1 = { }, pc2 = { } } } cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } return cfg 96udulomlrz3r693i5iidr5pj9sm7i4 28304 28303 2014-06-09T10:20:00Z w>Mr. Stradivarius 0 restructure banners table 28304 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { } cfg.banners.move.vandalism = { } cfg.banners.create = { } cfg.banners.autoreview.pc1 = { } cfg.banners.autoreview.pc2 = { } cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } return cfg ct2mqrkimz9g57aqmlzi1fu3j8m2t5l 28305 28304 2014-06-09T23:44:57Z w>Mr. Stradivarius 0 add icon text 28305 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 = the icon-reason, prefixed with ", " cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { } cfg.banners.move.vandalism = { } cfg.banners.create = { } cfg.banners.autoreview.pc1 = { } cfg.banners.autoreview.pc2 = { } -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. cfg['icon-text-pc1'] = 'All edits by unregistered and new users are subject to review' cfg['icon-text-pc2'] = 'All edits by users who are not reviewers or administrators are subject to review' cfg['icon-text-template'] = 'This is a permanently protected $4' cfg['icon-text-default'] = 'This $4 is $8$9$10' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } return cfg sh2hzxhon1zgq06b09a7j6bhegl7rvj 28306 28305 2014-06-09T23:54:19Z w>Mr. Stradivarius 0 add alt text 28306 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 = the icon-reason, prefixed with ", " cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { } cfg.banners.move.vandalism = { } cfg.banners.create = { } cfg.banners.autoreview.pc1 = { } cfg.banners.autoreview.pc2 = { } -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. cfg['icon-text-pc1'] = 'All edits by unregistered and new users are subject to review' cfg['icon-text-pc2'] = 'All edits by users who are not reviewers or administrators are subject to review' cfg['icon-text-template'] = 'This is a permanently protected $4' cfg['icon-text-default'] = 'This $4 is $8$9$10' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- cfg['alt-text-template'] = 'Permanently protected $4' cfg['alt-text-pc1'] = 'Page protected with pending changes level 1' cfg['alt-text-pc2'] = 'Page protected with pending changes level 2' cfg['alt-text-semi'] = 'Page semi-protected' cfg['alt-text-move'] = 'Page move-protected' cfg['alt-text-indef'] = 'Page permanently protected' cfg['alt-text-create'] = 'Page creation-protected' cfg['alt-text-office'] = '' cfg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } return cfg kc125pb56edhptaxlb1v6g33dsk3wqp 28307 28306 2014-06-10T00:05:38Z w>Mr. Stradivarius 0 add reason text 28307 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 = the icon-reason, prefixed with ", " cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { } cfg.banners.move.vandalism = { } cfg.banners.create = { } cfg.banners.autoreview.pc1 = { } cfg.banners.autoreview.pc2 = { } -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. cfg['icon-text-pc1'] = 'All edits by unregistered and new users are subject to review' cfg['icon-text-pc2'] = 'All edits by users who are not reviewers or administrators are subject to review' cfg['icon-text-template'] = 'This is a permanently protected $4' cfg['icon-text-default'] = 'This $4 is $8$9$10' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- cfg['alt-text-template'] = 'Permanently protected $4' cfg['alt-text-pc1'] = 'Page protected with pending changes level 1' cfg['alt-text-pc2'] = 'Page protected with pending changes level 2' cfg['alt-text-semi'] = 'Page semi-protected' cfg['alt-text-move'] = 'Page move-protected' cfg['alt-text-indef'] = 'Page permanently protected' cfg['alt-text-create'] = 'Page creation-protected' cfg['alt-text-office'] = '' cfg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- cfg['alt-text-full'] = 'This $4 is currently [[Help:Protection|protected]] from editing' cfg['alt-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access levels#New users|new]] or [[Wikipedia:User access levels#Unregistered users|unregistered]] users is currently [[Help:Protection|disabled]]$9' cfg['alt-text-pc1'] = 'All edits made to this $4 by [[Wikipedia:User access levels#New users|new]] or [[Wikipedia:User access levels#Unregistered users|unregistered]] users are currently [[Wikipedia:Pending changes|subject to review]]$9' cfg['alt-text-pc2'] = 'All edits made to this $4 by users who are not [[Wikipedia:Reviewing|reviewers]] or [[Wikipedia:Administrators|administrators]] are currently [[Wikipedia:Pending changes|subject to review]]$9' cfg['alt-text-move'] = 'This $4 is currently [[Help:Protection|protected]] from [[Help:Moving a page|page moves]]$9' cfg['alt-text-template'] = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$9' cfg['alt-text-indef'] = "This page is [[Help:Protection|protected]] from editing ''indefinitely''$9" cfg['alt-text-office'] = 'This $4 is currently [[Help:Protection|protected]] from editing$9' cfg['alt-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4 [[Help:Protection|has been disabled]]$9' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } return cfg 6z8vz7a13r5tkyzijo97u9u8fq6b89m 28308 28307 2014-06-10T01:20:16Z w>Mr. Stradivarius 0 add explanation text 28308 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 = the icon-reason, prefixed with ", " -- $11 = A link to the page history, with display cfg['dispute-edit-link-display'] -- $12 = A link to the move log, with display cfg['dispute-move-link-display'] -- $13 = A link to the protection log or the pending changes log, with display cfg['more-details-protection-log-display'] or cfg['more-details-pc-log-display'] -- $14 = Talk page link -- $15 = Edit request link -- $16 = Request unprotection blurb -- $17 = Adds links to edit requests and the talk page if we are on a subject page -- $18 = Deletion discussion link -- $19 = Deletion log link cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $11", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $12" } cfg.banners.move.vandalism = { } cfg.banners.create = { } cfg.banners.autoreview.pc1 = { } cfg.banners.autoreview.pc2 = { } -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. cfg['icon-text-pc1'] = 'All edits by unregistered and new users are subject to review' cfg['icon-text-pc2'] = 'All edits by users who are not reviewers or administrators are subject to review' cfg['icon-text-template'] = 'This is a permanently protected $4' cfg['icon-text-default'] = 'This $4 is $8$9$10' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- cfg['alt-text-template'] = 'Permanently protected $4' cfg['alt-text-pc1'] = 'Page protected with pending changes level 1' cfg['alt-text-pc2'] = 'Page protected with pending changes level 2' cfg['alt-text-semi'] = 'Page semi-protected' cfg['alt-text-move'] = 'Page move-protected' cfg['alt-text-indef'] = 'Page permanently protected' cfg['alt-text-create'] = 'Page creation-protected' cfg['alt-text-office'] = '' cfg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- cfg['alt-text-full'] = 'This $4 is currently [[Help:Protection|protected]] from editing' cfg['alt-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access levels#New users|new]] or [[Wikipedia:User access levels#Unregistered users|unregistered]] users is currently [[Help:Protection|disabled]]$9' cfg['alt-text-pc1'] = 'All edits made to this $4 by [[Wikipedia:User access levels#New users|new]] or [[Wikipedia:User access levels#Unregistered users|unregistered]] users are currently [[Wikipedia:Pending changes|subject to review]]$9' cfg['alt-text-pc2'] = 'All edits made to this $4 by users who are not [[Wikipedia:Reviewing|reviewers]] or [[Wikipedia:Administrators|administrators]] are currently [[Wikipedia:Pending changes|subject to review]]$9' cfg['alt-text-move'] = 'This $4 is currently [[Help:Protection|protected]] from [[Help:Moving a page|page moves]]$9' cfg['alt-text-template'] = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$9' cfg['alt-text-indef'] = "This page is [[Help:Protection|protected]] from editing ''indefinitely''$9" cfg['alt-text-office'] = 'This $4 is currently [[Help:Protection|protected]] from editing$9' cfg['alt-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4 [[Help:Protection|has been disabled]]$9' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- cfg['dispute-move-link-display'] = 'current title' cfg['dispute-edit-link-display'] = 'current version' cfg['more-details'] = 'See the [[Wikipedia:Protection policy|protection policy]] and $13 for more details.' cfg['more-details-pc-log-display'] = 'pending changes log' cfg['more-details-protection-log-display'] = 'protection log' cfg['talk-page-link-display'] = 'talk page' cfg['edit-request-full-display'] = 'submit a request' cfg['edit-request-semi-display'] = 'request an edit' cfg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for page protection#Current requests for reduction in protection level|request]] that this page be unprotected.' cfg['semi-subject-page-links'] = ' $15, discuss changes on the $14,' cfg['deletion-log-link-display'] = 'deletion log' cfg['explanation-text-full'] = 'Please discuss any changes on the $14; you may $15 to ask an [[Wikipedia:Administrators|administrator]] to make an edit if it is [[Help:Minor edit#When to mark an edit as a minor edit|uncontroversial]] or supported by [[Wikipedia:Consensus|consensus]].$16' cfg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make a change, you can$17 [[Wikipedia:Requests for page protection#Current requests for reduction in protection level|request unprotection]], [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|create an account]].' cfg['explanation-text-move'] = 'The page may still be edited but cannot be moved until unprotected. Please discuss any suggested moves on the $14 or at [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for page protection|request]] that the page be unprotected.' cfg['explanation-text-template'] = 'Please discuss any changes on the $14; you may $15 to ask an [[Wikipedia:Administrators|administrator]] or [[Wikipedia:Template editor|template editor]] to make an edit if it is [[Help:Minor edit#When to mark an edit as a minor edit|uncontroversial]] or supported by [[Wikipedia:Consensus|consensus]].$16' cfg['explanation-text-office'] = "If you can edit this page, please discuss all changes and additions on the $14 first. '''Do not remove protection from this page unless you are authorized by the Wikimedia Foundation to do so.'''" cfg['explanation-text-create'] = 'Please see the$18 $19 for details of why this page was deleted. If you would like to create a page at this title, you must first [[Wikipedia:Requests for page protection|request]] for it to be unprotected, or contact the administrator who deleted the page for the deleted material to be restored. If unsuccessful, you can use [[Wikipedia:Deletion review|deletion review]].' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } cfg.categories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } cfg.categoryNamespaces = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.pagetypeNamespaces = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } cfg.errorCategories = { incorrect = 'Wikipedia pages with incorrect protection templates', noExpiry = 'Wikipedia protected pages without expiry', create = 'Wikipedia pages tagged as create-protected', template = 'Wikipedia template-protected pages other than templates and modules' } return cfg d7nbsl3tuvkz814d752l881oiwmy8pz 28309 28308 2014-06-12T00:29:29Z w>Mr. Stradivarius 0 put messages and config tables in separate tables 28309 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 = the icon-reason, prefixed with ", " -- $11 = A link to the page history, with display msg['dispute-edit-link-display'] -- $12 = A link to the move log, with display msg['dispute-move-link-display'] -- $13 = A link to the protection log or the pending changes log, with display msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $14 = Talk page link -- $15 = Edit request link -- $16 = Request unprotection blurb -- $17 = Adds links to edit requests and the talk page if we are on a subject page -- $18 = Deletion discussion link -- $19 = Deletion log link cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $11", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $12" } cfg.banners.move.vandalism = { } cfg.banners.create = { } cfg.banners.autoreview.pc1 = { } cfg.banners.autoreview.pc2 = { } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-pc1'] = 'All edits by unregistered and new users are subject to review' msg['icon-text-pc2'] = 'All edits by users who are not reviewers or administrators are subject to review' msg['icon-text-template'] = 'This is a permanently protected $4' msg['icon-text-default'] = 'This $4 is $8$9$10' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-template'] = 'Permanently protected $4' msg['alt-text-pc1'] = 'Page protected with pending changes level 1' msg['alt-text-pc2'] = 'Page protected with pending changes level 2' msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-indef'] = 'Page permanently protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-office'] = '' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-full'] = 'This $4 is currently [[Help:Protection|protected]] from editing' msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access levels#New users|new]] or [[Wikipedia:User access levels#Unregistered users|unregistered]] users is currently [[Help:Protection|disabled]]$9' msg['reason-text-pc1'] = 'All edits made to this $4 by [[Wikipedia:User access levels#New users|new]] or [[Wikipedia:User access levels#Unregistered users|unregistered]] users are currently [[Wikipedia:Pending changes|subject to review]]$9' msg['reason-text-pc2'] = 'All edits made to this $4 by users who are not [[Wikipedia:Reviewing|reviewers]] or [[Wikipedia:Administrators|administrators]] are currently [[Wikipedia:Pending changes|subject to review]]$9' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]] from [[Help:Moving a page|page moves]]$9' msg['reason-text-template'] = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$9' msg['reason-text-indef'] = "This page is [[Help:Protection|protected]] from editing ''indefinitely''$9" msg['reason-text-office'] = 'This $4 is currently [[Help:Protection|protected]] from editing$9' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4 [[Help:Protection|has been disabled]]$9' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|protection policy]] and $13 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for page protection#Current requests for reduction in protection level|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $15, discuss changes on the $14,' msg['deletion-log-link-display'] = 'deletion log' msg['explanation-text-full'] = 'Please discuss any changes on the $14; you may $15 to ask an [[Wikipedia:Administrators|administrator]] to make an edit if it is [[Help:Minor edit#When to mark an edit as a minor edit|uncontroversial]] or supported by [[Wikipedia:Consensus|consensus]].$16' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make a change, you can$17 [[Wikipedia:Requests for page protection#Current requests for reduction in protection level|request unprotection]], [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved until unprotected. Please discuss any suggested moves on the $14 or at [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for page protection|request]] that the page be unprotected.' msg['explanation-text-template'] = 'Please discuss any changes on the $14; you may $15 to ask an [[Wikipedia:Administrators|administrator]] or [[Wikipedia:Template editor|template editor]] to make an edit if it is [[Help:Minor edit#When to mark an edit as a minor edit|uncontroversial]] or supported by [[Wikipedia:Consensus|consensus]].$16' msg['explanation-text-office'] = "If you can edit this page, please discuss all changes and additions on the $14 first. '''Do not remove protection from this page unless you are authorized by the Wikimedia Foundation to do so.'''" msg['explanation-text-create'] = 'Please see the$18 $19 for details of why this page was deleted. If you would like to create a page at this title, you must first [[Wikipedia:Requests for page protection|request]] for it to be unprotected, or contact the administrator who deleted the page for the deleted material to be restored. If unsuccessful, you can use [[Wikipedia:Deletion review|deletion review]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 7bsqg68uyd1bka6ni5h7i9jz34mxbdn 28310 28309 2014-06-12T00:52:21Z w>Mr. Stradivarius 0 move template explanation text to a new banner config table 28310 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 = the icon-reason, prefixed with ", " -- $11 = A link to the page history, with display msg['dispute-edit-link-display'] -- $12 = A link to the move log, with display msg['dispute-move-link-display'] -- $13 = A link to the protection log or the pending changes log, with display msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $14 = Talk page link -- $15 = Edit request link -- $16 = Request unprotection blurb -- $17 = Adds links to edit requests and the talk page if we are on a subject page -- $18 = Deletion discussion link -- $19 = Deletion log link -- $20 = {{#ifeq:{{NAMESPACE}}|{{ns:6}}|image, included in a high-risk template or message,|high-risk {{pp-meta/pagetype}} }} -- $21 = "semi-protected from editing", "protected from editing" or "move-protected" cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $11", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This $20 is permanently $21 to prevent vandalism', explanation = 'Please discuss any changes on the $14; you may $15 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$16' } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $12" } cfg.banners.move.vandalism = { } cfg.banners.create = { } cfg.banners.autoreview.pc1 = { } cfg.banners.autoreview.pc2 = { } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-pc1'] = 'All edits by unregistered and new users are subject to review' msg['icon-text-pc2'] = 'All edits by users who are not reviewers or administrators are subject to review' msg['icon-text-template'] = 'This is a permanently protected $4' msg['icon-text-default'] = 'This $4 is $8$9$10' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-template'] = 'Permanently protected $4' msg['alt-text-pc1'] = 'Page protected with pending changes level 1' msg['alt-text-pc2'] = 'Page protected with pending changes level 2' msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-indef'] = 'Page permanently protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-office'] = '' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-full'] = 'This $4 is currently [[Help:Protection|protected]] from editing' msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access levels#New users|new]] or [[Wikipedia:User access levels#Unregistered users|unregistered]] users is currently [[Help:Protection|disabled]]$9' msg['reason-text-pc1'] = 'All edits made to this $4 by [[Wikipedia:User access levels#New users|new]] or [[Wikipedia:User access levels#Unregistered users|unregistered]] users are currently [[Wikipedia:Pending changes|subject to review]]$9' msg['reason-text-pc2'] = 'All edits made to this $4 by users who are not [[Wikipedia:Reviewing|reviewers]] or [[Wikipedia:Administrators|administrators]] are currently [[Wikipedia:Pending changes|subject to review]]$9' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]] from [[Help:Moving a page|page moves]]$9' msg['reason-text-template'] = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$9' msg['reason-text-indef'] = "This page is [[Help:Protection|protected]] from editing ''indefinitely''$9" msg['reason-text-office'] = 'This $4 is currently [[Help:Protection|protected]] from editing$9' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4 [[Help:Protection|has been disabled]]$9' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|protection policy]] and $13 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for page protection#Current requests for reduction in protection level|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $15, discuss changes on the $14,' msg['deletion-log-link-display'] = 'deletion log' msg['explanation-text-full'] = 'Please discuss any changes on the $14; you may $15 to ask an [[Wikipedia:Administrators|administrator]] to make an edit if it is [[Help:Minor edit#When to mark an edit as a minor edit|uncontroversial]] or supported by [[Wikipedia:Consensus|consensus]].$16' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make a change, you can$17 [[Wikipedia:Requests for page protection#Current requests for reduction in protection level|request unprotection]], [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved until unprotected. Please discuss any suggested moves on the $14 or at [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for page protection|request]] that the page be unprotected.' msg['explanation-text-office'] = "If you can edit this page, please discuss all changes and additions on the $14 first. '''Do not remove protection from this page unless you are authorized by the Wikimedia Foundation to do so.'''" msg['explanation-text-create'] = 'Please see the$18 $19 for details of why this page was deleted. If you would like to create a page at this title, you must first [[Wikipedia:Requests for page protection|request]] for it to be unprotected, or contact the administrator who deleted the page for the deleted material to be restored. If unsuccessful, you can use [[Wikipedia:Deletion review|deletion review]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } jewpdqo6w70g33xhn9q50gpa1qdbsgd 28311 28310 2014-06-16T01:43:13Z w>Mr. Stradivarius 0 various simplifications and formatting 28311 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 = the icon-reason, prefixed with ", " -- $11 = A link to the page history, with display msg['dispute-edit-link-display'] -- $12 = A link to the move log, with display msg['dispute-move-link-display'] -- $13 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $14 = Talk page link -- $15 = Edit request link -- $16 = Request unprotection blurb -- $17 = Adds links to edit requests and the talk page if we are on a subject page -- $18 = Deletion discussion link -- $19 = Deletion log link -- $20 = {{#ifeq:{{NAMESPACE}}|{{ns:6}}|image, included in a high-risk template or message,|high-risk {{pp-meta/pagetype}} }} -- $21 = "semi-protected from editing", "protected from editing" or "move-protected" -- $22 = "This protection is '''not''' an endorsement of the current version" cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = '$22', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$9', explanation = 'Please discuss any changes on the $14; you may $15 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$16', tooltip = 'This high-risk $4 is permanently $21 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $14 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $14 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $12" } cfg.banners.move.vandalism = { } cfg.banners.create = { } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$9', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$9', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', pc1 = 'Padlock-silver-light.svg', pc2 = 'Padlock-orange.svg', move = 'Padlock-olive.svg', indef = 'Padlock-red.svg', office = 'Padlock-black.svg', create = 'Padlock-skyblue.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $8$9$10' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$9' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$9' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$9' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $13 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $15, discuss changes on the $14,' msg['deletion-log-link-display'] = 'deletion log' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$17 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $14 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = 'Please see the$18 $19 for details of why this' .. ' page was deleted. If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $14; you' .. ' may $15 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$16' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 5mwzpoeuysqri6u9ckmy5vf675yelro 28312 28311 2014-06-16T01:48:36Z w>Mr. Stradivarius 0 move images to the banner config if possible 28312 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = A blurb "it has been protected for x years, x months and x days." -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 = the icon-reason, prefixed with ", " -- $11 = A link to the page history, with display msg['dispute-edit-link-display'] -- $12 = A link to the move log, with display msg['dispute-move-link-display'] -- $13 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $14 = Talk page link -- $15 = Edit request link -- $16 = Request unprotection blurb -- $17 = Adds links to edit requests and the talk page if we are on a subject page -- $18 = Deletion discussion link -- $19 = Deletion log link -- $20 = {{#ifeq:{{NAMESPACE}}|{{ns:6}}|image, included in a high-risk template or message,|high-risk {{pp-meta/pagetype}} }} -- $21 = "semi-protected from editing", "protected from editing" or "move-protected" -- $22 = "This protection is '''not''' an endorsement of the current version" cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = '$22', tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$9', explanation = 'Please discuss any changes on the $14; you may $15 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$16', tooltip = 'This high-risk $4 is permanently $21 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. $5', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $14 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $14 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits, such' .. ' as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $12", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$9', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$9', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', indef = 'Padlock-red.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $8$9$10' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$9' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$9' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$9' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $13 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $15, discuss changes on the $14,' msg['deletion-log-link-display'] = 'deletion log' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$17 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $14 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = 'Please see the$18 $19 for details of why this' .. ' page was deleted. If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $14; you' .. ' may $15 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$16' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } qd9dlg53p72f9c0nmczid2e7vdof71j 28313 28312 2014-06-16T02:02:07Z w>Mr. Stradivarius 0 remove some parameters we don't need 28313 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 removed -- $6 = the protection date -- $7 = {{vandal-m|username}} replacement -- $8 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $9 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $10 removed -- $11 = A link to the page history, with display msg['dispute-edit-link-display'] -- $12 = A link to the move log, with display msg['dispute-move-link-display'] -- $13 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $14 = Talk page link -- $15 = Edit request link -- $16 = Request unprotection blurb -- $17 = Adds links to edit requests and the talk page if we are on a subject page -- $18 = Deletion discussion link -- $19 = Deletion log link -- $20 removed -- $21 removed -- $22 removed cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $11.", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$9', explanation = 'Please discuss any changes on the $14; you may $15 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$16', tooltip = 'This high-risk $4 is permanently $8 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $6.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $14 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $6 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $14 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $7 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $12", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$9', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$9', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', indef = 'Padlock-red.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $8$9' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$9' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$9' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$9' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $13 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $15, discuss changes on the $14,' msg['deletion-log-link-display'] = 'deletion log' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$17 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $14 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = 'Please see the$18 $19 for details of why this' .. ' page was deleted. If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $14; you' .. ' may $15 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$16' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 7c07kaqfqgdef2n5avhgwxdw8w5gny9 28314 28313 2014-06-16T02:11:21Z w>Mr. Stradivarius 0 renumber parameters 28314 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion discussion link -- $16 = Deletion log link cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $10", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', indef = 'Padlock-red.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $7$8' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-log-link-display'] = 'deletion log' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = 'Please see the$15 $16 for details of why this' .. ' page was deleted. If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } bmdk8t7ywgyobua7dzhpkuln8sc7d1t 28315 28314 2014-06-16T03:14:49Z w>Mr. Stradivarius 0 add a disputes display message 28315 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion discussion link -- $16 = Deletion log link cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $10", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', indef = 'Padlock-red.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $7$8' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-log-link-display'] = 'deletion log' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = 'Please see the$15 $16 for details of why this' .. ' page was deleted. If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } hv9e1t3l04y3dhspy6vsuh307zxfmmu 28316 28315 2014-06-19T01:40:35Z w>Mr. Stradivarius 0 add protection level messages 28316 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion discussion link -- $16 = Deletion log link cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $10", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', indef = 'Padlock-red.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $7$8' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-log-link-display'] = 'deletion log' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = 'Please see the$15 $16 for details of why this' .. ' page was deleted. If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } qc5sm24nhbgdgwd8bjn3r6huecv8ixi 28317 28316 2014-06-19T06:37:18Z w>Mr. Stradivarius 0 re-jig the deletion blurb messages 28317 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $10", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { full = 'Padlock.svg', semi = 'Padlock-silver.svg', template = 'Padlock-pink.svg', indef = 'Padlock-red.svg' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $7$8' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = '$15 If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } plmcmf2m0a0pyhrf7j2v02e0sbzjfx7 28318 28317 2014-06-20T07:03:00Z w>Mr. Stradivarius 0 new structure for the image filename data 28318 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. '[[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $10", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $7$8' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = '$15 If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } c6jpto53n4yl6x3o76f06e41pg2na0h 28319 28318 2014-06-22T23:25:29Z w>Mr. Stradivarius 0 add missing space 28319 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- A table of protection banners, sorted by protection type. -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', dispute = true, categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $10", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Icon text -------------------------------------------------------------------------------- -- Parameters are the same as for the banner table. msg['icon-text-default'] = 'This $4 is $7$8' -------------------------------------------------------------------------------- -- Alt text -------------------------------------------------------------------------------- msg['alt-text-semi'] = 'Page semi-protected' msg['alt-text-move'] = 'Page move-protected' msg['alt-text-create'] = 'Page creation-protected' msg['alt-text-default'] = 'Page protected' -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details.' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = '$15 If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } h0rd8n044s2uyihdjpya9nc8eikfps1 28320 28319 2014-06-23T06:48:03Z w>Mr. Stradivarius 0 restructure a little and add default banner config details 28320 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg, msg = {}, {} -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. -- All banner config messages can use the following parameters: -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link -- $18 = The explanation text, based on the protection action and level. cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.edit.autoconfirmed = { alt = 'Page semi-protected' } cfg.defaultBanners.edit.templateeditor = { alt = 'Page template-protected' } cfg.defaultBanners.edit.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected' } cfg.defaultBanners.move.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page move-protected' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page creation-protected' } cfg.defaultBanners.create.reviewer = { alt = 'Page protected with pending changes level 2' } cfg.defaultBanners.create.autoconfirmed = { alt = 'Page protected with pending changes level 1' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected with pending changes' } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $9", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = '$15 If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 2821aazf794ch0rdre2tq48teij7vwb 28321 28320 2014-06-23T10:28:31Z w>Mr. Stradivarius 0 add table of strings marking indefinite protection 28321 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg, msg = {}, {} -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. -- All banner config messages can use the following parameters: -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link -- $18 = The explanation text, based on the protection action and level. cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.edit.autoconfirmed = { alt = 'Page semi-protected' } cfg.defaultBanners.edit.templateeditor = { alt = 'Page template-protected' } cfg.defaultBanners.edit.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected' } cfg.defaultBanners.move.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page move-protected' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page creation-protected' } cfg.defaultBanners.create.reviewer = { alt = 'Page protected with pending changes level 2' } cfg.defaultBanners.create.autoconfirmed = { alt = 'Page protected with pending changes level 1' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected with pending changes' } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]]', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $9", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = '$15 If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } gh8gm8fxceijgii3jrf3mr63o48zbu2 28322 28321 2014-06-23T14:10:14Z w>Mr. Stradivarius 0 add some missing full stops 28322 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg, msg = {}, {} -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. -- All banner config messages can use the following parameters: -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link -- $18 = The explanation text, based on the protection action and level. cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.edit.autoconfirmed = { alt = 'Page semi-protected' } cfg.defaultBanners.edit.templateeditor = { alt = 'Page template-protected' } cfg.defaultBanners.edit.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected' } cfg.defaultBanners.move.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page move-protected' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page creation-protected' } cfg.defaultBanners.create.reviewer = { alt = 'Page protected with pending changes level 2' } cfg.defaultBanners.create.autoconfirmed = { alt = 'Page protected with pending changes level 1' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected with pending changes' } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved.', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', categoryReason = 'office', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $9", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.categoryPagetypes = { [2] = 'user', [3] = 'user', [4] = 'project', [6] = 'file', [10] = 'template', [12] = 'project', [14] = 'category', [100] = 'portal', } cfg.bannerPagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = '$15 If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 9cpyhy1lf6swybjmkkobx871yqj0frg 28323 28322 2014-06-24T13:32:30Z w>Mr. Stradivarius 0 use a new approach to the banner config, allowing more fine-grained control and less hopping around between parameter definitions 28323 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- Banner data -------------------------------------------------------------------------------- --[[ -- The following banner data fields are available: -- text, explanation, tooltip, alt, image, category -- -- When the module is asked to retrieve one of these data fields, it looks in -- the cfg.bannerData table. It uses five properties in its search: -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- For each data field, the module will check to see if the field exists in the -- table with the key corresponding to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- This makes it possible to specify fine-grained distinctions in banner text. -- For example, data defined for the key "all-user-vandalism-all-edit" can be -- used for user pages that are protected either temporarily or permanently, -- and either fully protected or semi-protected, but it won't be used for -- articles or for pages protected against sockpuppetry. -- -- Note that the fields don't have to be in the same table. A given banner -- might use text from "temp-user-vandalism-autoconfirmed-edit" but a -- category from "all-all-vandalism-all-edit". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. -- -- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- --]] cfg.bannerDataNamespaceHasPriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the bannerData -- table. vandalism = true, } cfg.bannerDataNamespaceKeys = { -- The string to use as a namespace key for bannerData for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.bannerData = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = { text = '', explanation = '', tooltip = '', alt = '', category = 'Wikipedia protected pages', }, ['all-all-office-all-all'] = { category = 'Wikipedia Office-protected pages', }, ['all-all-reset-all-all'] = { category = 'Wikipedia Office-protected pages', }, ['all-template-all-all-edit'] = { category = 'Wikipedia protected templates', }, ['all-all-all-autoconfirmed-edit'] = { category = 'Wikipedia semi-protected pages', }, ['indef-all-all-autoconfirmed-edit'] = { category = 'Wikipedia indefinitely semi-protected pages', }, ['all-all-blp-autoconfirmed-edit'] = { category = 'Wikipedia indefinitely semi-protected biographies of living people', }, ['temp-all-blp-autoconfirmed-edit'] = { category = 'Wikipedia temporarily semi-protected biographies of living people', }, ['all-all-dispute-autoconfirmed-edit'] = { category = 'Wikipedia pages semi-protected due to dispute', }, ['all-all-sock-autoconfirmed-edit'] = { category = 'Wikipedia pages semi-protected from banned users', }, ['all-all-vandalism-autoconfirmed-edit'] = { category = 'Wikipedia pages semi-protected against vandalism', }, ['all-category-all-autoconfirmed-edit'] = { category = 'Wikipedia semi-protected categories', }, ['all-file-all-autoconfirmed-edit'] = { category = 'Semi-protected images', }, ['all-portal-all-autoconfirmed-edit'] = { category = 'Semi-protected portals', }, ['all-project-all-autoconfirmed-edit'] = { category = 'Semi-protected project pages', }, ['all-talk-all-autoconfirmed-edit'] = { category = 'Semi-protected talk pages', }, ['all-template-all-autoconfirmed-edit'] = { category = 'Wikipedia semi-protected templates', }, ['all-template-all-autoconfirmed-edit'] = { category = 'Wikipedia semi-protected templates', }, ['all-user-all-autoconfirmed-edit'] = { category = 'Wikipedia semi-protected user and user talk pages', }, ['all-all-blp-sysop-edit'] = { category = 'Wikipedia indefinitely protected biographies of living people', }, ['temp-all-blp-sysop-edit'] = { category = 'Wikipedia temporarily protected biographies of living people', }, ['all-all-dispute-sysop-edit'] = { category = 'Wikipedia pages protected due to dispute', }, ['all-all-sock-sysop-edit'] = { category = 'Wikipedia pages protected from banned users', }, ['all-all-vandalism-sysop-edit'] = { category = 'Wikipedia pages protected against vandalism', }, ['all-category-all-sysop-edit'] = { category = 'Wikipedia protected categories', }, ['all-file-all-sysop-edit'] = { category = 'Protected images', }, ['all-project-all-sysop-edit'] = { category = 'Protected project pages', }, ['all-talk-all-sysop-edit'] = { category = 'Protected talk pages', }, ['all-template-all-sysop-edit'] = { category = 'Wikipedia protected templates', }, ['all-user-all-sysop-edit'] = { category = 'Wikipedia protected user and user talk pages', }, ['all-all-all-sysop-move'] = { category = 'Wikipedia move-protected pages', }, ['indef-all-all-sysop-move'] = { category = 'Wikipedia indefinitely move-protected pages', }, ['all-all-dispute-sysop-move'] = { category = 'Wikipedia pages move-protected due to dispute', }, ['all-all-vandalism-sysop-move'] = { category = 'Wikipedia pages move-protected due to vandalism', }, ['all-portal-all-sysop-move'] = { category = 'Wikipedia move-protected portals', }, ['all-portal-all-sysop-move'] = { category = 'Wikipedia move-protected portals', }, ['all-project-all-sysop-move'] = { category = 'Wikipedia move-protected project pages', }, ['all-talk-all-sysop-move'] = { category = 'Wikipedia move-protected talk pages', }, ['all-template-all-sysop-move'] = { category = 'Wikipedia move-protected templates', }, ['all-user-all-sysop-move'] = { category = 'Wikipedia move-protected user and user talk pages', }, ['all-all-all-autoconfirmed-autoreview'] = { category = 'Wikipedia pending changes protected pages (level 1)', }, ['all-all-all-reviewer-autoreview'] = { category = 'Wikipedia pending changes protected pages (level 2)', }, } -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. -- All banner config messages can use the following parameters: -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link -- $18 = The explanation text, based on the protection action and level. -- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.edit.autoconfirmed = { alt = 'Page semi-protected' } cfg.defaultBanners.edit.templateeditor = { alt = 'Page template-protected' } cfg.defaultBanners.edit.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected' } cfg.defaultBanners.move.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page move-protected' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page creation-protected' } cfg.defaultBanners.create.reviewer = { alt = 'Page protected with pending changes level 2' } cfg.defaultBanners.create.autoconfirmed = { alt = 'Page protected with pending changes level 1' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected with pending changes' } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved.', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $9", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-reset-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['request-unprotection-blurb'] = ' You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' msg['explanation-text-semi'] = 'If you cannot edit this $4 and you wish to make' .. ' a change, you can$14 [[Wikipedia:Requests for page protection#Current' .. ' requests for reduction in protection level|request unprotection]],' .. ' [[Special:Userlogin|log in]], or [[Special:UserLogin/signup|' .. 'create an account]].' msg['explanation-text-move'] = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the $11 or at' .. ' [[Wikipedia:Requested moves]]. You can also [[Wikipedia:Requests for' .. ' page protection|request]] that the page be unprotected.' msg['explanation-text-create'] = '$15 If you would like to create a page at this title,' .. ' you must first [[Wikipedia:Requests for page protection|request]] for' .. ' it to be unprotected, or contact the administrator who deleted the' .. ' page for the deleted material to be restored. If unsuccessful, you can' .. ' use [[Wikipedia:Deletion review|deletion review]].' msg['explanation-text-default'] = 'Please discuss any changes on the $11; you' .. ' may $12 to ask an [[Wikipedia:Administrators|administrator]] to make' .. ' an edit if it is [[Help:Minor edit#When to mark an edit as a minor' .. ' edit|uncontroversial]] or supported by [[Wikipedia:Consensus|' .. 'consensus]].$13' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 360ctthkglwvkx781qr2t3xqtu7zrjt 28324 28323 2014-06-25T06:58:05Z w>Mr. Stradivarius 0 more conversion of the data to the bannerConfig table 28324 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- --[[ -- The following banner data fields are available: -- text, explanation, tooltip, alt, image, category -- -- When the module is asked to retrieve one of these data fields, it looks in -- the cfg.bannerData table. It uses five properties in its search: -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- For each data field, the module will check to see if the field exists in the -- table with the key corresponding to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- This makes it possible to specify fine-grained distinctions in banner text. -- For example, data defined for the key "all-user-vandalism-all-edit" can be -- used for user pages that are protected either temporarily or permanently, -- and either fully protected or semi-protected, but it won't be used for -- articles or for pages protected against sockpuppetry. -- -- Note that the fields don't have to be in the same table. A given banner -- might use text from "temp-user-vandalism-autoconfirmed-edit" but a -- category from "all-all-vandalism-all-edit". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. -- -- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${TALKPAGELINK} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${DELETIONREASONSBLURB} - a blurb about why the page was deleted. For -- example, "Please see the deletion discussion or the protection log for -- details of why this page was deleted." Uses the message -- "deletion-discussion-blurb-xfd" if a link to a deletion discussion is -- present, or "deletion-discussion-blurb-noxfd" if not. --]] cfg.bannerDataNamespaceHasPriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the bannerData -- table. vandalism = true, } cfg.bannerDataNamespaceKeys = { -- The string to use as a namespace key for bannerData for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } -------------------------------------------------------------------------------- -- Intro text -------------------------------------------------------------------------------- -- Shared intro text for the bannerData table. local introText = {} introText.full = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from editing' introText.semi = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access levels' .. '#New users|new]] or [[Wikipedia:User access levels#Unregistered users' .. '|unregistered]] users is currently [[Help:Protection|disabled]]' introText.move = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' introText.create = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' -------------------------------------------------------------------------------- -- Banner data table -------------------------------------------------------------------------------- cfg.bannerData = {} -- Set the defaults for all protection types. cfg.bannerData['all-all-all-all-all'] = { text = introText.full .. '.', explanation = 'Please discuss any changes on the ${TALKPAGELINK}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', alt = 'Page ${PROTECTIONLEVEL}', image = 'Transparent.gif', category = 'Wikipedia protected pages' } -- Move-protection defaults. cfg.bannerData['all-all-all-all-move'] = { explanation = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGELINK} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', } -- Create-protection defaults. cfg.bannerData['all-all-all-all-create'] = { explanation = '${DELETIONBLURB} If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].', } -- Don't make an unprotection request link for pages in the MediaWiki namespace. cfg.bannerData['all-mediawiki-all-all-all'] = { text = introText.full .. '.', explanation = 'Please discuss any changes on the ${TALKPAGELINK}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', } -- Set defaults for temporarily-protected pages. cfg.bannerData['temp-all-all-all-all'] = { text = introText.full .. ' until ${EXPIRY}.', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.' } cfg.bannerData['all-all-all-autoconfirmed-edit'] = { text = introText.semi .. '.' } cfg.bannerData['temp-all-all-autoconfirmed-edit'] = { text = introText.semi .. ' until ${EXPIRY}.' } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- local bannerDataCategories = { ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } for key, cat in pairs(bannerDataCategories) do local t = cfg.bannerData[key] or {} t.category = cat cfg.bannerData[key] = t end -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. -- All banner config messages can use the following parameters: -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link -- $18 = The explanation text, based on the protection action and level. -- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.edit.autoconfirmed = { alt = 'Page semi-protected' } cfg.defaultBanners.edit.templateeditor = { alt = 'Page template-protected' } cfg.defaultBanners.edit.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected' } cfg.defaultBanners.move.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page move-protected' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page creation-protected' } cfg.defaultBanners.create.reviewer = { alt = 'Page protected with pending changes level 2' } cfg.defaultBanners.create.autoconfirmed = { alt = 'Page protected with pending changes level 1' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected with pending changes' } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved.', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $9", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-reset-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } nzpqfx1rep4ha0ijjyit3xihyehiugv 28325 28324 2014-06-25T11:51:53Z w>Mr. Stradivarius 0 further conversion to new bannerData scheme 28325 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- --[[ -- The following banner data fields are available: -- text, explanation, tooltip, alt, image, category -- -- When the module is asked to retrieve one of these data fields, it looks in -- the cfg.bannerData table. It uses five properties in its search: -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- For each data field, the module will check to see if the field exists in the -- table with the key corresponding to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- This makes it possible to specify fine-grained distinctions in banner text. -- For example, data defined for the key "all-user-vandalism-all-edit" can be -- used for user pages that are protected either temporarily or permanently, -- and either fully protected or semi-protected, but it won't be used for -- articles or for pages protected against sockpuppetry. -- -- Note that the fields don't have to be in the same table. A given banner -- might use text from "temp-user-vandalism-autoconfirmed-edit" but a -- category from "all-all-vandalism-all-edit". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. -- -- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${TALKPAGELINK} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${DELETIONREASONSBLURB} - a blurb about why the page was deleted. For -- example, "Please see the deletion discussion or the protection log for -- details of why this page was deleted." Uses the message -- "deletion-discussion-blurb-xfd" if a link to a deletion discussion is -- present, or "deletion-discussion-blurb-noxfd" if not. -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. --]] cfg.bannerDataNamespaceHasPriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the bannerData -- table. vandalism = true, } cfg.bannerDataNamespaceKeys = { -- The string to use as a namespace key for bannerData for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } -------------------------------------------------------------------------------- -- Intro text -------------------------------------------------------------------------------- -- Shared intro text for the bannerData table. local introText = {} introText.move = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' introText.create = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' -------------------------------------------------------------------------------- -- Banner data table -------------------------------------------------------------------------------- -- Shared explanation text for the bannerData table. local explanationText = {} explanationText.moreDetails = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' -------------------------------------------------------------------------------- -- Banner data table -------------------------------------------------------------------------------- cfg.bannerData = {} -- Set the defaults for all protection types. cfg.bannerData['all-all-all-all-all'] = { text = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from editing.', explanation = 'Please discuss any changes on the ${TALKPAGELINK}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', alt = 'Page ${PROTECTIONLEVEL}', image = 'Transparent.gif', category = 'Wikipedia protected pages' } -- Move-protection defaults. cfg.bannerData['all-all-all-all-move'] = { explanation = 'The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGELINK} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', } -- Create-protection defaults. cfg.bannerData['all-all-all-all-create'] = { explanation = '${DELETIONBLURB} If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].', } -- Don't make an unprotection request link for pages in the MediaWiki namespace. cfg.bannerData['all-mediawiki-all-all-all'] = { explanation = 'Please discuss any changes on the ${TALKPAGELINK}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', } -- Set defaults for temporarily-protected pages. cfg.bannerData['temp-all-all-all-all'] = { text = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from editing until ${EXPIRY}.', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', } -- Semi-protected pages. cfg.bannerData['all-all-all-autoconfirmed-edit'] = { text = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access levels' .. '#New users|new]] or [[Wikipedia:User access levels#Unregistered users' .. '|unregistered]] users is currently [[Help:Protection|disabled]].', } -- Temporarily semi-protected pages. cfg.bannerData['temp-all-all-autoconfirmed-edit'] = { text = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access levels' .. '#New users|new]] or [[Wikipedia:User access levels#Unregistered users' .. '|unregistered]] users is currently [[Help:Protection|disabled]]' .. ' until ${EXPIRY}.', } -- Move-protected pages. cfg.bannerData['all-all-all-all-move'] = { text = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]].', } -- Temporarily move-protected pages. cfg.bannerData['temp-all-all-all-move'] = { text = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]] until ${EXPIRY}.', } -- Create-protected pages. cfg.bannerData['all-all-all-all-create'] = { text = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]].', } -- Create-protected pages. cfg.bannerData['temp-all-all-all-create'] = { text = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]] until ${EXPIRY}.', } -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- local bannerDataCategories = { ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } for key, cat in pairs(bannerDataCategories) do local t = cfg.bannerData[key] or {} t.category = cat cfg.bannerData[key] = t end -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. -- All banner config messages can use the following parameters: -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link -- $18 = The explanation text, based on the protection action and level. -- cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.edit.autoconfirmed = { alt = 'Page semi-protected' } cfg.defaultBanners.edit.templateeditor = { alt = 'Page template-protected' } cfg.defaultBanners.edit.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected' } cfg.defaultBanners.move.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page move-protected' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page creation-protected' } cfg.defaultBanners.create.reviewer = { alt = 'Page protected with pending changes level 2' } cfg.defaultBanners.create.autoconfirmed = { alt = 'Page protected with pending changes level 1' } cfg.defaultBanners.create.default = { text = '$1.', explanation = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and $10 for more details. $18', tooltip = 'This $4 is $7$8.', alt = 'Page protected with pending changes' } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '$1 to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '$1 to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '$1 $2 editing $3 have been resolved.', explanation = "This protection is '''not''' an endorsement of the $9.", tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] $4, as it is [[Wikipedia:High-risk templates|high-risk]]$8', explanation = 'Please discuss any changes on the $11; you may $12 to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]].$13', tooltip = 'This high-risk $4 is permanently $7 to prevent vandalism', alt = 'Permanently protected $4', } cfg.banners.edit.office = { text = 'This $4 is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '$1 to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '$1 to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '$1 to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '$1 due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '$1 due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $9", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.pc1 = { text = 'All edits made to this $4 by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.pc2 = { text = 'All edits made to this $4 by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.protectionCategories = { -- The key strings follow this format: -- type, level, ns, reason, expiry ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-all-office-all'] = 'Wikipedia Office-protected pages', ['all-all-all-reset-all'] = 'Wikipedia Office-protected pages', ['edit-all-template-all-all'] = 'Wikipedia protected templates', ['edit-autoconfirmed-all-all-all'] = 'Wikipedia semi-protected pages', ['edit-autoconfirmed-all-all-indef'] = 'Wikipedia indefinitely semi-protected pages', ['edit-autoconfirmed-all-blp-all'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['edit-autoconfirmed-all-blp-temp'] = 'Wikipedia temporarily semi-protected biographies of living people', ['edit-autoconfirmed-all-dispute-all'] = 'Wikipedia pages semi-protected due to dispute', ['edit-autoconfirmed-all-sock-all'] = 'Wikipedia pages semi-protected from banned users', ['edit-autoconfirmed-all-vandalism-all'] = 'Wikipedia pages semi-protected against vandalism', ['edit-autoconfirmed-category-all-all'] = 'Wikipedia semi-protected categories', ['edit-autoconfirmed-file-all-all'] = 'Semi-protected images', ['edit-autoconfirmed-portal-all-all'] = 'Semi-protected portals', ['edit-autoconfirmed-project-all-all'] = 'Semi-protected project pages', ['edit-autoconfirmed-talk-all-all'] = 'Semi-protected talk pages', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-template-all-all'] = 'Wikipedia semi-protected templates', ['edit-autoconfirmed-user-all-all'] = 'Wikipedia semi-protected user and user talk pages', ['edit-sysop-all-blp-all'] = 'Wikipedia indefinitely protected biographies of living people', ['edit-sysop-all-blp-temp'] = 'Wikipedia temporarily protected biographies of living people', ['edit-sysop-all-dispute-all'] = 'Wikipedia pages protected due to dispute', ['edit-sysop-all-sock-all'] = 'Wikipedia pages protected from banned users', ['edit-sysop-all-vandalism-all'] = 'Wikipedia pages protected against vandalism', ['edit-sysop-category-all-all'] = 'Wikipedia protected categories', ['edit-sysop-file-all-all'] = 'Protected images', ['edit-sysop-project-all-all'] = 'Protected project pages', ['edit-sysop-talk-all-all'] = 'Protected talk pages', ['edit-sysop-template-all-all'] = 'Wikipedia protected templates', ['edit-sysop-user-all-all'] = 'Wikipedia protected user and user talk pages', ['move-sysop-all-all-all'] = 'Wikipedia move-protected pages', ['move-sysop-all-all-indef'] = 'Wikipedia indefinitely move-protected pages', ['move-sysop-all-dispute-all'] = 'Wikipedia pages move-protected due to dispute', ['move-sysop-all-vandalism-all'] = 'Wikipedia pages move-protected due to vandalism', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-portal-all-all'] = 'Wikipedia move-protected portals', ['move-sysop-project-all-all'] = 'Wikipedia move-protected project pages', ['move-sysop-talk-all-all'] = 'Wikipedia move-protected talk pages', ['move-sysop-template-all-all'] = 'Wikipedia move-protected templates', ['move-sysop-user-all-all'] = 'Wikipedia move-protected user and user talk pages', ['autoreview-autoconfirmed-all-all-all'] = 'Wikipedia pending changes protected pages (level 1)', ['autoreview-reviewer-all-all-all'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Reason text -------------------------------------------------------------------------------- msg['reason-text-semi'] = 'Editing of this $4 by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]$8' msg['reason-text-move'] = 'This $4 is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]$8' msg['reason-text-create'] = '[[Help:Starting a new page|Recreation]] of this $4' .. ' [[Help:Protection|has been disabled]]$8' msg['reason-text-default'] = 'This $4 is currently [[Help:Protection|' .. 'protected]] from editing' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['dispute-section-link-display'] = 'disputes' msg['dispute-move-link-display'] = 'current title' msg['dispute-edit-link-display'] = 'current version' msg['more-details-pc-log-display'] = 'pending changes log' msg['more-details-protection-log-display'] = 'protection log' msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' msg['deletion-discussion-blurb-xfd'] = 'Please see the $16 or the $17 for' .. ' details of why this page was deleted.' msg['deletion-discussion-blurb-noxfd'] = 'Please see the $17 for' .. ' details of why this page was deleted.' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 1ogn5pan8fe7uasrsptprxiduydoexf 28326 28325 2014-06-25T14:04:01Z w>Mr. Stradivarius 0 use the old banner config style, but with the new parameter name scheme, and make more messages based on sentences rather than on snippets 28326 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- --[[ -- The following banner data fields are available: -- text, explanation, tooltip, alt, image, category -- -- When the module is asked to retrieve one of these data fields, it looks in -- the cfg.bannerData table. It uses five properties in its search: -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- For each data field, the module will check to see if the field exists in the -- table with the key corresponding to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- This makes it possible to specify fine-grained distinctions in banner text. -- For example, data defined for the key "all-user-vandalism-all-edit" can be -- used for user pages that are protected either temporarily or permanently, -- and either fully protected or semi-protected, but it won't be used for -- articles or for pages protected against sockpuppetry. -- -- Note that the fields don't have to be in the same table. A given banner -- might use text from "temp-user-vandalism-autoconfirmed-edit" but a -- category from "all-all-vandalism-all-edit". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. -- -- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATEBLURB} - a blurb explaining when the page was protected, e.g. -- "It was protected -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. -- All banner config messages can use the following parameters: -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link -- $18 = The explanation text, based on the protection action and level. cfg.defaultBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', alt = 'Page ${PROTECTIONLEVEL}' } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = 'This ${PAGETYPE} is currently under the scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since $5.', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = 'On $5 this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the $11 first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '${TOOLTIPBLURB} due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $9", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.create = { image = 'Padlock-skyblue.svg' } cfg.banners.autoreview.autoconfirmed = { text = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.default = { text = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]$8', alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION} have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION} have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Explanation text -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' msg['semi-subject-page-links'] = ' $12, discuss changes on the $11,' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- msg['protection-level-full'] = 'fully protected' msg['protection-level-template'] = 'template-protected' msg['protection-level-semi'] = 'semi-protected' msg['protection-level-move'] = 'move-protected' msg['protection-level-create'] = 'creation-protected' msg['protection-level-default'] = 'protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 0ovdgrj3ymt68488ltdosul5sihn7k8 28327 28326 2014-06-25T23:48:15Z w>Mr. Stradivarius 0 further conversion 28327 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- --[[ -- The following banner data fields are available: -- text, explanation, tooltip, alt, image, category -- -- When the module is asked to retrieve one of these data fields, it looks in -- the cfg.bannerData table. It uses five properties in its search: -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- For each data field, the module will check to see if the field exists in the -- table with the key corresponding to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- This makes it possible to specify fine-grained distinctions in banner text. -- For example, data defined for the key "all-user-vandalism-all-edit" can be -- used for user pages that are protected either temporarily or permanently, -- and either fully protected or semi-protected, but it won't be used for -- articles or for pages protected against sockpuppetry. -- -- Note that the fields don't have to be in the same table. A given banner -- might use text from "temp-user-vandalism-autoconfirmed-edit" but a -- category from "all-all-vandalism-all-edit". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. -- -- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. -- All banner config messages can use the following parameters: -- $1 = Intro blurb, e.g. "This page is currently -- [[Help:Protection|protected]] from editing" -- $2 = "until" or "or until" depending on the expiry -- $3 = "disputes", with or without a section link -- $4 = the type of the page, e.g. "article", "template", or "page" -- $5 = the protection date -- $6 = {{vandal-m|username}} replacement -- $7 = protection level/type blurb, e.g. "create-protected" or "fully protected" -- $8 = the expiry - " until DD Month YYYY". If protection is indefinite, this is the blank string. -- $9 = A link to the page history or the move log, with display -- msg['dispute-edit-link-display'] or msg['dispute-move-link-display'] -- $10 = A link to the protection log or the pending changes log, with display -- msg['more-details-protection-log-display'] or msg['more-details-pc-log-display'] -- $11 = Talk page link -- $12 = Edit request link -- $13 = Request unprotection blurb -- $14 = Adds links to edit requests and the talk page if we are on a subject page -- $15 = Deletion links blurb -- $16 = Deletion discussion link -- $17 = Deletion log link -- $18 = The explanation text, based on the protection action and level. cfg.defaultBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent $6 from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '${TOOLTIPBLURB} due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the $9", image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } cfg.banners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.banners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- msg['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.' msg['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' text = 'On ${PROTECTIONDATE} this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } lrnijki7mhzud5lqnv25rcvtbuj56uh 28328 28327 2014-06-26T01:47:43Z w>Mr. Stradivarius 0 get rid of the last of the numbered parameters, and move the binary matrix explanation down to the protectionCategories section 28328 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. cfg.masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.defaultBanners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '${TOOLTIPBLURB} due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- msg['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.' msg['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' msg['deletion-log-link-display'] = 'deletion log' text = 'On ${PROTECTIONDATE} this article was reduced to a simplified,' ..' "bare bones" version so that it may be completely rewritten to' .. ' ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } c78m6ivp1nwvneo2wqgqi99ctsyt07n 28329 28328 2014-06-26T13:34:59Z w>Mr. Stradivarius 0 remove unused deletion log message, and finish the reset blurb messages 28329 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. cfg.masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.defaultBanners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '${TOOLTIPBLURB} due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- msg['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.' msg['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- msg['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' msg['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } b2g5eopj2ryryyymmzppq1zn9uahcc5 28330 28329 2014-06-26T23:31:50Z w>Mr. Stradivarius 0 add a table for reasons that don't need expiry checks 28330 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. cfg.masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.defaultBanners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '${TOOLTIPBLURB} due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. cfg.reasonsWithoutExpiryCheck = { blp = true, } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- msg['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.' msg['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- msg['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' msg['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } jdbe542vehbdpjcvedll5z5tb337a2e 28331 28330 2014-06-26T23:39:10Z w>Mr. Stradivarius 0 add another table, for the actions to check 28331 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. cfg.masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.defaultBanners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '${TOOLTIPBLURB} due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. cfg.reasonsWithoutExpiryCheck = { blp = true, } -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. cfg.expiryCheckActions = { edit = true, move = false, create = false, autoreview = true } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- msg['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.' msg['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- msg['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' msg['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } ejjz0xd9f657ieamjwl54xifndet5os 28332 28331 2014-06-27T01:17:15Z w>Mr. Stradivarius 0 add 'all-all-all-all-all' protection category key back in 28332 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. cfg.masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.defaultBanners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', categoryOrder = 'reason', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', categoryOrder = 'reason', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', categoryOrder = 'reason', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', categoryOrder = 'reason', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', categoryReason = 'all', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]]', tooltip = '${TOOLTIPBLURB} due to vandalism', categoryOrder = 'namespace', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. cfg.reasonsWithoutExpiryCheck = { blp = true, } -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. cfg.expiryCheckActions = { edit = true, move = false, create = false, autoreview = true } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- msg['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.' msg['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- msg['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' msg['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } pokp8nzqa6an5vv31m6llfu8n19fa9g 28333 28332 2014-06-27T04:08:04Z w>Mr. Stradivarius 0 remove deprecated bannerData fields, add missing full stop to the vandalism banner 28333 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. cfg.masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.defaultBanners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. cfg.reasonsWithoutExpiryCheck = { blp = true, } -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. cfg.expiryCheckActions = { edit = true, move = false, create = false, autoreview = true } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- msg['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.' msg['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- msg['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' msg['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } 9jg33zdd2b9iegq0c8ihg0mircbwwhh 28334 28333 2014-06-27T05:21:26Z w>Mr. Stradivarius 0 add image link config 28334 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. cfg.masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.defaultBanners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- cfg.imageLinks = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.imageLinks.edit.default = 'Wikipedia:Protection policy#full' cfg.imageLinks.edit.templateeditor = 'Wikipedia:Protection policy#template' cfg.imageLinks.edit.autoconfirmed = 'Wikipedia:Protection policy#semi' cfg.imageLinks.move.default = 'Wikipedia:Protection policy#move' cfg.imageLinks.create.default = 'Wikipedia:Protection policy#create' cfg.imageLinks.autoreview.autoconfirmed = 'Wikipedia:Protection policy#pc1' cfg.imageLinks.autoreview.reviewer = 'Wikipedia:Protection policy#pc2' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. cfg.reasonsWithoutExpiryCheck = { blp = true, } -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. cfg.expiryCheckActions = { edit = true, move = false, create = false, autoreview = true } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = {} -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- msg['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}' msg['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}' -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- msg['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}' msg['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- msg['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.' msg['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].' msg['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' msg['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].' msg['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- msg['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.' msg['dispute-section-link-display'] = 'disputes' -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- msg['protection-log-display'] = 'protection log' msg['pc-log-display'] = 'pending changes log' -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- msg['current-version-move-display'] = 'current title' msg['current-version-edit-display'] = 'current version' -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- msg['talk-page-link-display'] = 'talk page' -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- msg['edit-request-full-display'] = 'submit a request' msg['edit-request-semi-display'] = 'request an edit' -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- msg['deletion-discussion-link-display'] = 'deletion discussion' -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- msg['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.' msg['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- msg['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' msg['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- msg['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates' msg['tracking-category-expiry'] = 'Wikipedia protected pages without expiry' msg['tracking-category-create'] = 'Wikipedia pages tagged as create-protected' msg['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. msg['image-filename-indef'] = 'Padlock-red.svg' msg['image-filename-default'] = 'Transparent.gif' -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } kcgxuq7f8z9qiz4qtmnr5kspmt2yvky 28335 28334 2014-06-28T17:34:14Z w>Jackmcbarn 0 construct msg all at once 28335 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. local cfg = {} -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. cfg.masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' } cfg.defaultBanners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.defaultBanners.autoreview.autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' } cfg.defaultBanners.autoreview.default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- cfg.banners = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.banners.edit.blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', } cfg.banners.edit.dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', } cfg.banners.edit.template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', } cfg.banners.edit.office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', } cfg.banners.edit.reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', } cfg.banners.edit.sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', } cfg.banners.edit.usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', } cfg.banners.edit.vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } cfg.banners.move.dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' } cfg.banners.move.vandalism = { } -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- cfg.protectionBlurbs = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionBlurbs.edit.default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing' cfg.protectionBlurbs.edit.autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' cfg.protectionBlurbs.move.default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' cfg.protectionBlurbs.create.default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' cfg.protectionBlurbs.autoreview.autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' cfg.protectionBlurbs.autoreview.default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- cfg.protectionLevels = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.protectionLevels.edit.default = 'protected' cfg.protectionLevels.edit.templateeditor = 'template-protected' cfg.protectionLevels.edit.autoconfirmed = 'semi-protected' cfg.protectionLevels.move.default = 'move-protected' cfg.protectionLevels.create.default = 'creation-protected' -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- cfg.images = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.images.edit.sysop = 'Padlock.svg' cfg.images.edit.templateeditor = 'Padlock-pink.svg' cfg.images.edit.autoconfirmed = 'Padlock-silver.svg' cfg.images.move.sysop = 'Padlock-olive.svg' cfg.images.move.templateeditor = 'Padlock-olive.svg' cfg.images.create.default = 'Padlock-skyblue.svg' cfg.images.autoreview.autoconfirmed = 'Padlock-silver-light.svg' cfg.images.autoreview.reviewer = 'Padlock-orange.svg' -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- cfg.imageLinks = { edit = {}, move = {}, create = {}, autoreview = {} } cfg.imageLinks.edit.default = 'Wikipedia:Protection policy#full' cfg.imageLinks.edit.templateeditor = 'Wikipedia:Protection policy#template' cfg.imageLinks.edit.autoconfirmed = 'Wikipedia:Protection policy#semi' cfg.imageLinks.move.default = 'Wikipedia:Protection policy#move' cfg.imageLinks.create.default = 'Wikipedia:Protection policy#create' cfg.imageLinks.autoreview.autoconfirmed = 'Wikipedia:Protection policy#pc1' cfg.imageLinks.autoreview.reviewer = 'Wikipedia:Protection policy#pc2' -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] cfg.reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, } cfg.categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', } cfg.protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', } -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. cfg.reasonsWithoutExpiryCheck = { blp = true, } -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. cfg.expiryCheckActions = { edit = true, move = false, create = false, autoreview = true } -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- cfg.pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' } -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- cfg.indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, } -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- local msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].', ['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- ['deletion-discussion-link-display'] = 'deletion discussion', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- return { cfg = cfg, msg = msg } sbkpy6m9qsh81hiyas3an5unjjth8n9 28336 28335 2014-06-28T17:47:03Z w>Jackmcbarn 0 build the whole config all at once, and combine cfg and msg 28336 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, create = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { } }, create = {}, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, create = { default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, create = { default = 'creation-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, create = { default = 'Padlock-skyblue.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, create = { default = 'Wikipedia:Protection policy#create' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, create = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].', ['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- ['deletion-discussion-link-display'] = 'deletion discussion', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } r69wmloecit01ogmw4obdcbbyzxgky7 28337 28336 2014-06-29T10:47:50Z w>Mr. Stradivarius 0 add padlock position data 28337 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DELETIONDISCUSSION} - a link to the deletion discussion, if a link -- to it was specified. -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, create = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { } }, create = {}, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, create = { default = '[[Help:Starting a new page|Recreation]] of this ${PAGETYPE}' .. ' [[Help:Protection|has been disabled]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, create = { default = 'creation-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, create = { default = 'Padlock-skyblue.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, create = { default = 'Wikipedia:Protection policy#create' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, create = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-create-xfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${DELETIONDISCUSSION}' .. ' or the ${PROTECTIONLOG} for' .. ' details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].', ['explanation-blurb-create-noxfd'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please see the ${PROTECTIONLOG}' .. ' for details of why this page was deleted. If you would like to create a page' .. ' at this title, you must first' .. ' [[Wikipedia:Requests for page protection|request]] for it to be' .. ' unprotected, or contact the administrator who deleted the page for the' .. ' deleted material to be restored. If unsuccessful, you can use' .. ' [[Wikipedia:Deletion review|deletion review]].', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Deletion blurb -------------------------------------------------------------------------------- ['deletion-discussion-link-display'] = 'deletion discussion', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } f0l560m5spn82k2xjrsjgq0fhxgi2ib 28338 28337 2014-06-29T18:35:17Z w>Jackmcbarn 0 rm stuff that would only be useful for pp-create and other things unused in favor of salting 28338 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } dy0wwkf4jlgxzyte0x5817g7hoechbv 28339 28338 2014-07-01T02:24:43Z w>Mr. Stradivarius 0 add a description field to each of the banners for auto-generating some of the documentation 28339 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. '[[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } dsx7d4844q55wen9tb60xsm8xj72l0p 28340 28339 2014-07-01T02:55:08Z w>Mr. Stradivarius 0 add documentation messages 28340 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. '[[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Documentation -------------------------------------------------------------------------------- ['documentation-heading-reason'] = 'Reason', ['documentation-heading-action'] = 'Action', ['documentation-heading-description'] = 'Description', ['documentation-blurb-noreasons'] = 'No reason values were found in the module' .. ' configuration.', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 1drk0i8nh8rjf83glzxs9qzdg0j0zse 28341 28340 2014-07-01T06:50:55Z w>Mr. Stradivarius 0 add missing space 28341 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Documentation -------------------------------------------------------------------------------- ['documentation-heading-reason'] = 'Reason', ['documentation-heading-action'] = 'Action', ['documentation-heading-description'] = 'Description', ['documentation-blurb-noreasons'] = 'No reason values were found in the module' .. ' configuration.', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } c6tpw9khaszcjz0gsvrxn1tu9hdsjnp 28342 28341 2014-07-03T06:48:37Z w>Mr. Stradivarius 0 remove the documentation messages 28342 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } o08pvlxw9m55kw1bjz1jivibn9nrktk 28343 28342 2014-07-03T07:01:06Z w>Mr. Stradivarius 0 add error message blurb 28343 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${DISPUTEBLURB} - a blurb about editing disputes, using the INTROBLURB -- parameter and the DISPUTESECTION parameter. E.g. "This page is protected -- from editing until disputes have been resolved." -- -- ${DISPUTESECTION} - if a section link is passed to the module, this is -- a link to that section with the display message -- "dispute-section-link-display". Otherwise it is just the display -- message with no link. -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${OFFICEBLURB} - a blurb about pages protected by the WMF office. If the -- protection date has been specified, includes a sentence saying when the page -- was protected. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${RESETBLURB} - a blurb for pages using {{pp-reset}}. If the protection -- date is specified, this includes information about when the page was -- protected. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = '${DISPUTEBLURB}', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = '${OFFICEBLURB}', explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = '${RESETBLURB}' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''", explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Dispute blurb -------------------------------------------------------------------------------- ['dispute-blurb-expiry'] = '${INTROBLURB} or until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-blurb-noexpiry'] = '${INTROBLURB} until editing ${DISPUTESECTION}' .. ' have been resolved.', ['dispute-section-link-display'] = 'disputes', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Office blurb -------------------------------------------------------------------------------- ['office-blurb-protectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected. It has been protected since ${PROTECTIONDATE}.', ['office-blurb-noprotectiondate'] = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } c2lfclypnkcmrwvw420rcnocjaq16kc 28344 28343 2014-07-03T16:10:27Z w>Mr. Stradivarius 0 convert the following parameters to use functions inside the config: DISPUTEBLURB, DISPUTESECTION, OFFICEBLURB, RESETBLURB 28344 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. 'reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } qnveeqtolrjqlrfjzpyc78xin6a9l4z 28345 28344 2014-07-03T16:13:24Z w>Mr. Stradivarius 0 add missing space 28345 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, -------------------------------------------------------------------------------- -- Reset blurb -------------------------------------------------------------------------------- ['reset-blurb-protectiondate'] = 'On ${PROTECTIONDATE} this article was' .. ' reduced to a simplified, "bare bones" version so that it may be' .. ' completely rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', ['reset-blurb-noprotectiondate'] = 'This article has been reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].', reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } dcc3y05q8n6fzbsc00wf4lluboix63t 28346 28345 2014-07-05T02:44:29Z w>Mr. Stradivarius 0 oops, forgot to remove the reset blurb messages I was working from 28346 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } fs65c68rc9j864fhw872u9dmwkynoul 28347 28346 2014-07-05T02:54:16Z w>Mr. Stradivarius 0 use the dispute notice with the vandalism template if the page is fully protected 28347 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, blurbData) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end ret = ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } iqgoobp74gpck47c0nu126k77bkrkjr 28348 28347 2014-07-05T02:55:16Z w>Mr. Stradivarius 0 actually return the ret value from the function 28348 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, blurbData) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } m2fkh2shjwnymfhep8akoa919b6ewo0 28349 28348 2014-07-05T04:27:22Z w>Jackmcbarn 0 random idea, just to get it into the page history 28349 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, blurbData) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'main-page'}, -- XXX The module doesn't support this reason yet. ['Template:Pp-meta'] = {}, -- XXX Do we need this one, or is pp-meta going away? ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'office-dmca'}, -- XXX The module doesn't support this reason yet. ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } gpino2z6rq4s81y48p9isq8vo4rjl2l 28350 28349 2014-07-05T04:27:35Z w>Jackmcbarn 0 Reverted edits by [[Special:Contribs/Jackmcbarn|Jackmcbarn]] ([[User talk:Jackmcbarn|talk]]) to last version by Mr. Stradivarius 28350 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, blurbData) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } m2fkh2shjwnymfhep8akoa919b6ewo0 28351 28350 2014-07-06T14:01:03Z w>Mr. Stradivarius 0 reinstate the wrappers table and add the mainpage reason 28351 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, blurbData) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-all-mainpage-all-all'] = 'Protected main page images', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'main-page', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'office-dmca'}, -- XXX The module doesn't support this reason yet. ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } gpxz8pzg2vg3svv19xc2qzbiinix55z 28352 28351 2014-07-06T14:37:52Z w>Mr. Stradivarius 0 add dmca reason 28352 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionDate, blurbData) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if blurbData.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. blurbData.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, blurbData) -- Find the value of "disputes". local display = 'disputes' local disputes if blurbData.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, blurbData.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionDate, blurbData) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, blurbData) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, blurbData) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-all-dmca-all-all'] = 'Wikipedia Office-protected pages', ['all-all-mainpage-all-all'] = 'Protected main page images', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } ex6qduo4za7u0d9j5qp2csm4s7qr97p 28353 28352 2014-07-06T14:47:04Z w>Mr. Stradivarius 0 fix parameter names for the banner data functions 28353 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all-all-all-all-all'] = 'Wikipedia protected pages', ['all-all-office-all-all'] = 'Wikipedia Office-protected pages', ['all-all-reset-all-all'] = 'Wikipedia Office-protected pages', ['all-all-dmca-all-all'] = 'Wikipedia Office-protected pages', ['all-all-mainpage-all-all'] = 'Protected main page images', ['all-template-all-all-edit'] = 'Wikipedia protected templates', ['all-all-all-autoconfirmed-edit'] = 'Wikipedia semi-protected pages', ['indef-all-all-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected pages', ['all-all-blp-autoconfirmed-edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp-all-blp-autoconfirmed-edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all-all-dispute-autoconfirmed-edit'] = 'Wikipedia pages semi-protected due to dispute', ['all-all-sock-autoconfirmed-edit'] = 'Wikipedia pages semi-protected from banned users', ['all-all-vandalism-autoconfirmed-edit'] = 'Wikipedia pages semi-protected against vandalism', ['all-category-all-autoconfirmed-edit'] = 'Wikipedia semi-protected categories', ['all-file-all-autoconfirmed-edit'] = 'Semi-protected images', ['all-portal-all-autoconfirmed-edit'] = 'Semi-protected portals', ['all-project-all-autoconfirmed-edit'] = 'Semi-protected project pages', ['all-talk-all-autoconfirmed-edit'] = 'Semi-protected talk pages', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-template-all-autoconfirmed-edit'] = 'Wikipedia semi-protected templates', ['all-user-all-autoconfirmed-edit'] = 'Wikipedia semi-protected user and user talk pages', ['all-all-blp-sysop-edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp-all-blp-sysop-edit'] = 'Wikipedia temporarily protected biographies of living people', ['all-all-dispute-sysop-edit'] = 'Wikipedia pages protected due to dispute', ['all-all-sock-sysop-edit'] = 'Wikipedia pages protected from banned users', ['all-all-vandalism-sysop-edit'] = 'Wikipedia pages protected against vandalism', ['all-category-all-sysop-edit'] = 'Wikipedia protected categories', ['all-file-all-sysop-edit'] = 'Protected images', ['all-project-all-sysop-edit'] = 'Protected project pages', ['all-talk-all-sysop-edit'] = 'Protected talk pages', ['all-template-all-sysop-edit'] = 'Wikipedia protected templates', ['all-user-all-sysop-edit'] = 'Wikipedia protected user and user talk pages', ['all-all-all-sysop-move'] = 'Wikipedia move-protected pages', ['indef-all-all-sysop-move'] = 'Wikipedia indefinitely move-protected pages', ['all-all-dispute-sysop-move'] = 'Wikipedia pages move-protected due to dispute', ['all-all-vandalism-sysop-move'] = 'Wikipedia pages move-protected due to vandalism', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-portal-all-sysop-move'] = 'Wikipedia move-protected portals', ['all-project-all-sysop-move'] = 'Wikipedia move-protected project pages', ['all-talk-all-sysop-move'] = 'Wikipedia move-protected talk pages', ['all-template-all-sysop-move'] = 'Wikipedia move-protected templates', ['all-user-all-sysop-move'] = 'Wikipedia move-protected user and user talk pages', ['all-all-all-autoconfirmed-autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all-all-all-reviewer-autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } tc1jwl0hwk0inb658zfwdr8lzl79evg 28354 28353 2014-07-06T14:53:05Z w>Mr. Stradivarius 0 use pipes as separators instead of hyphens for the protection category keys - this is to help prevent the module being confused if users specify reasons with hyphens in them 28354 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB} or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } o1zbrtzl84nwd4cce3d9xdiuj7jmjpe 28355 28354 2014-07-10T01:17:33Z w>Mr. Stradivarius 0 add a message for the expiry date format 28355 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = 'due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } aw3pycg6ygtmf00qdgthhwngq3f77ud 28356 28355 2014-07-10T01:28:45Z w>Mr. Stradivarius 0 fix tooltip blurb for the dispute banner 28356 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 60w806y16yx5o4ki7xilo68k5yzb8j2 28357 28356 2014-07-10T03:43:00Z w>Mr. Stradivarius 0 add semi-protection explanation blurbs 28357 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-semi-subject'] = 'If you cannot edit this ${PAGETYPE}' .. ' and you wish to make a change, you can ${EDITREQUEST}, discuss changes' .. ' on the ${TALKPAGE}, [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', ['explanation-blurb-semi-talk'] = 'If you cannot edit this ${PAGETYPE}' .. ' and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 2vtflx8gxmdvxsgthfmoh9adyuq2i55 28358 28357 2014-07-10T04:41:16Z w>Mr. Stradivarius 0 add missing text from the semi-protection explanation blurbs 28358 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-full-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', ['explanation-blurb-full-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', ['explanation-blurb-semi-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', ['explanation-blurb-semi-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', ['explanation-blurb-move-subject'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-move-talk'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', ['explanation-blurb-default'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 35fus3p9lypij311zsisulk9l737f1n 28359 28358 2014-07-10T05:19:37Z w>Mr. Stradivarius 0 use an explanation blurbs table rather than hard-coding the messages in the module 28359 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 4xip2dcanwawnpiv5u2stu6tm7g1f8f 28360 28359 2014-07-10T05:24:01Z w>Mr. Stradivarius 0 better key for MediaWiki namespace explanation blurb message 28360 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } fpstti50wrnaouajsexbee3k17vi6o9 28361 28360 2014-07-11T13:55:07Z w>Mr. Stradivarius 0 add autoreview explanation blurbs 28361 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-full-display'] = 'submit a request', ['edit-request-semi-display'] = 'request an edit', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } n3xyl2kxf9z7y50kphkli42mlt64bhj 28362 28361 2014-07-19T03:56:25Z w>Mr. Stradivarius 0 only use one display value for edit requests 28362 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } e2zzrw24np6wkecnl17krm28z1xrxwx 28363 28362 2014-07-22T01:07:29Z w>Mr. Stradivarius 0 add missing punctuation 28363 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } siuykpesi9olchv2dh01eardki2lk0u 28364 28363 2014-07-22T01:12:32Z w>Mr. Stradivarius 0 add a comma after the intro blurb expiry 28364 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectiobObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 0sul922scjmmwsbtl9avatzhm497a3m 28365 28364 2014-07-22T01:14:48Z w>Mr. Stradivarius 0 fix variable name 28365 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been placed under a level of' .. ' semi-protection temporarily during the rebuilding of this' .. ' article.\n\nAny insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n'''Administrators may not override this action" .. ' without approval from someone from the [[WP:OFFICE|Office]].' .. " No editor may remove this notice.'''" return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 8gnkrwyqlq9pfiosa21ikodd07vpx7v 28366 28365 2014-07-22T01:27:40Z w>Mr. Stradivarius 0 copy edit the reset banner 28366 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the [[WP:OFFICE" .. "|Wikimedia Foundation]] to do so. No editor may remove this" .. " notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } i9tyngz1y9a42p0fh6eolqre5wsgjal 28367 28366 2014-07-22T01:29:58Z w>Mr. Stradivarius 0 putting a comma after the expiry doesn't work if there aren't any more words in the sentence - will need to think some more about this 28367 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the [[WP:OFFICE" .. "|Wikimedia Foundation]] to do so. No editor may remove this" .. " notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } d1oyc0e0jv7qp4gqw5wby5m1u965hev 28368 28367 2014-07-22T01:33:13Z w>Mr. Stradivarius 0 further copy editing of the reset banner 28368 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this article was' else ret = ret .. 'This article has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The article has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the article will be removed, as' .. ' will any material added to the article that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 9jzbt8eju05wotwxbp68osk6ordvps6 28369 28368 2014-07-22T01:35:18Z w>Mr. Stradivarius 0 use PAGETYPE variable with the reset reason 28369 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY" -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}.', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROBLURB} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROBLURB}, or until editing %s have been resolved.' else msg = '${INTROBLURB} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROBLURB} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROBLURB} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROBLURB} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 7y2ivkjdfc0hbsrnp95847vghmewdtl 28370 28369 2014-07-22T06:09:40Z w>Mr. Stradivarius 0 add an INTROFRAGMENT parameter to solve the problem of what punctuation to use in run-on sentences using INTROBLURB 28370 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview'}, ['Template:Pp-pc2'] = {action = 'autoreview'}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } b4jodelhn7ocoawd5wi13gbpt5aoyzj 28371 28370 2014-07-22T11:06:12Z w>Mr. Stradivarius 0 make [[Template:Pp-pc1]] and [[Template:Pp-pc2]] small by default 28371 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- The module will only output the "pages without expiry" tracking category -- for the actions set to true in the following table. expiryCheckActions = { edit = true, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } o8uit0z0wjema95v1g2cy8vxejm4bq0 28372 28371 2014-07-22T11:42:24Z w>Mr. Stradivarius 0 change the expiry category config behaviour to deal with [[Template:Pp-pc1]] and [[Template:Pp-pc2]] 28372 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if an expiry parameter -- is not set, if a reason is provided, and if the specified reason is not -- blacklisted in the reasonsWithoutExpiryCheck table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit'}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } j2ycdl8nlywu7pabw6v96l1ot8js085 28373 28372 2014-07-22T12:21:40Z w>Mr. Stradivarius 0 Pp-template needs to be small by default 28373 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- If any of the following reasons is passed to the module, it will not output -- the "pages without expiry" tracking category. reasonsWithoutExpiryCheck = { blp = true, }, -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if an expiry parameter -- is not set, if a reason is provided, and if the specified reason is not -- blacklisted in the reasonsWithoutExpiryCheck table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } imqrew4ro5sni1kyewmu5f7avk0q5b1 28374 28373 2014-07-22T12:29:39Z w>Mr. Stradivarius 0 templates shouldn't output a "needs expiry" category; also, update the comments 28374 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } k8n9a0iyvt8tizslz43x27spkl2e7ns 28375 28374 2014-07-23T01:44:16Z w>Mr. Stradivarius 0 add an indefImageReasons table 28375 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 3tqwma6p13wgomtvtb759gfohii72tp 28376 28375 2014-07-25T03:03:56Z w>Mr. Stradivarius 0 note which tables are required to have "edit", "move", and "autoreview" subtables 28376 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- BANNER DATA -------------------------------------------------------------------------------- -- PARAMETERS -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -------------------------------------------------------------------------------- -- Banner defaults -------------------------------------------------------------------------------- -- If no protection reason is specified, or no banner data exists for the -- reason given, then this data will be used for the banner. Individual items -- from this data will also be used if that item doesn't exist in the reason- -- specific banner config. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -------------------------------------------------------------------------------- -- Banner config -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on biographies of' .. ' living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- Messages -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } mbxccgok0ik2p3i6uwrldev878tq2ss 28377 28376 2014-08-05T14:27:41Z w>Mr. Stradivarius 0 add more comments 28377 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 1iypaa93vhfbyfdwr126rwdhvl22b3i 28378 28377 2014-08-05T15:12:05Z w>Mr. Stradivarius 0 add more comments; explain functions in the banner config and what some of the other config tables do 28378 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { sysop = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { sysop = 'Padlock-olive.svg', templateeditor = 'Padlock-olive.svg' }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', reviewer = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 4levrugzkdmx4ei0lapa4ffm9v4g638 28379 28378 2014-08-05T15:17:04Z w>Mr. Stradivarius 0 use default values in the images table, to make them future-proofed against new protection levels 28379 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- Sets the "right" CSS property for padlock icons, based on its protection -- action. This determines the position of the padlock among the other top -- icons. If no value is found for the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the cfg.protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] reasonsWithNamespacePriority = { -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. vandalism = true, }, categoryNamespaceKeys = { -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } nllivehkzqgra2274umljebbsajrx7b 28380 28379 2014-08-05T15:38:04Z w>Mr. Stradivarius 0 finish adding comments for all the general data tables 28380 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages in the MediaWiki namespace. ['explanation-blurb-mediawiki'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log links -------------------------------------------------------------------------------- ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version messages -------------------------------------------------------------------------------- ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-create'] = 'Wikipedia pages tagged as create-protected', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- $1 is replaced with the error message text. The whole message is turned into -- a large red error message, so there is no need to add HTML styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } mqz7n4v9f3211l1id1y9ldnkh8seu4c 28381 28380 2014-08-05T15:53:21Z w>Mr. Stradivarius 0 add comments to the messages, fix one wrong message name, and remove another that wasn't being used 28381 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- This is the blurb that is outputted with error messages produced by the -- module. $1 is replaced with the error message text. The whole message is -- turned into a large red error message, so there is no need to add HTML -- styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } b2tum4t3aqqvysbul0dfve9kh5atxbw 28382 28381 2014-08-05T17:18:13Z w>Mr. Stradivarius 0 Protected Module:Protection banner/config: [[WP:High-risk templates|High-risk Lua module]] ([Edit=Allow only template editors and admins] (indefinite) [Move=Allow only template editors and admins] (indefinite)) 28381 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef'}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- This is the blurb that is outputted with error messages produced by the -- module. $1 is replaced with the error message text. The whole message is -- turned into a large red error message, so there is no need to add HTML -- styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } b2tum4t3aqqvysbul0dfve9kh5atxbw 28383 28382 2014-08-05T19:36:17Z w>Mr. Stradivarius 0 make pp-semi-indef small by default 28383 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'j F, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- This is the blurb that is outputted with error messages produced by the -- module. $1 is replaced with the error message text. The whole message is -- turned into a large red error message, so there is no need to add HTML -- styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } emilvjt4vmwzy3phybwup1ojw1zx2mk 28384 28383 2014-08-08T13:31:37Z w>Mr. Stradivarius 0 set the expiry display to "F j, Y", as that's what [[Template:Pp-meta]] does 28384 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}.', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPBLURB} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPBLURB} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPBLURB} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- This is the blurb that is outputted with error messages produced by the -- module. $1 is replaced with the error message text. The whole message is -- turned into a large red error message, so there is no need to add HTML -- styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } h3snkue85qu1q86ynuk4w2jpa2mqn7q 28385 28384 2014-08-08T14:21:40Z w>Mr. Stradivarius 0 add tooltip fragment messages and convert existing TOOLTIPBLURB parameters to TOOLTIPFRAGMENT parameters where appropriate 28385 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp', action = 'edit'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute', action = 'edit'}, ['Template:Pp-main-page'] = {'mainpage', action = 'edit'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {action = 'edit'}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock', action = 'edit'}, ['Template:Pp-template'] = {'template', action = 'edit', small = true}, ['Template:Pp-usertalk'] = {'usertalk', action = 'edit'}, ['Template:Pp-vandalism'] = {'vandalism', action = 'edit'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- This is the blurb that is outputted with error messages produced by the -- module. $1 is replaced with the error message text. The whole message is -- turned into a large red error message, so there is no need to add HTML -- styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 57f0snad1qe6cv7wvvxchtry58wvaop 28386 28385 2014-08-14T04:59:52Z w>Mr. Stradivarius 0 remove instances of "action = 'edit'" from the wrappers table, as this no longer has any effect now that default arguments can be overwritten 28386 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-protected'] = {}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- This is the blurb that is outputted with error messages produced by the -- module. $1 is replaced with the error message text. The whole message is -- turned into a large red error message, so there is no need to add HTML -- styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 84jwjqfuz3o3qmz80diz1lnnhvdqkvq 28387 28386 2014-08-14T05:00:48Z w>Mr. Stradivarius 0 remove [[Template:Pp-protected]] from the wrappers table, as it is now a redirect to [[Template:Pp]] 28387 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- This is the blurb that is outputted with error messages produced by the -- module. $1 is replaced with the error message text. The whole message is -- turned into a large red error message, so there is no need to add HTML -- styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 4zp178t9nx28bgdua1ddppb6sxhbdef 28388 28387 2014-09-06T21:12:33Z w>Jackmcbarn 0 add hierarchy 28388 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, accountcreator = {'templateeditor'}, autoconfirmed = {'reviewer', 'filemover', 'accountcreator'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- Error message blurb -------------------------------------------------------------------------------- -- This is the blurb that is outputted with error messages produced by the -- module. $1 is replaced with the error message text. The whole message is -- turned into a large red error message, so there is no need to add HTML -- styling. ['error-message-blurb'] = 'Error: $1 ([[Module:Protection banner#Errors|help]])' -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } m8hjxrhtz1scvqz707hxvortaz4oj8a 28389 28388 2014-10-03T03:21:26Z w>Jackmcbarn 0 rm now-unused error message blurb 28389 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:List of banned users|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, accountcreator = {'templateeditor'}, autoconfirmed = {'reviewer', 'filemover', 'accountcreator'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 3f9smqq59o5b50g6e189kjn2yf6z9mt 28390 28389 2014-10-03T18:55:15Z w>28bytes 0 retarget ban link per MfD outcome 28390 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, accountcreator = {'templateeditor'}, autoconfirmed = {'reviewer', 'filemover', 'accountcreator'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } njdp1s329eo72gk6icz9vw4ne954umh 28391 28390 2014-11-12T01:59:36Z w>Mr. Stradivarius 0 add protected module categories 28391 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, accountcreator = {'templateeditor'}, autoconfirmed = {'reviewer', 'filemover', 'accountcreator'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 4u1nupyaek5tdfq2secpxnch19w5nzy 28392 28391 2014-11-12T02:01:28Z w>Mr. Stradivarius 0 Undid revision 633468191 by [[Special:Contributions/Mr. Stradivarius|Mr. Stradivarius]] ([[User talk:Mr. Stradivarius|talk]]) undo, sorry, that needs to be tested first 28392 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, accountcreator = {'templateeditor'}, autoconfirmed = {'reviewer', 'filemover', 'accountcreator'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } njdp1s329eo72gk6icz9vw4ne954umh 28393 28392 2014-11-12T02:43:15Z w>Cenarium 0 28393 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, accountcreator = {'templateeditor'}, autoconfirmed = {'reviewer', 'filemover', 'accountcreator'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 8hcffc3zxkmqt5lr5rv6qk8zusgqnbz 28394 28393 2014-11-12T02:48:11Z w>Cenarium 0 it was a null edit 28394 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, accountcreator = {'templateeditor'}, autoconfirmed = {'reviewer', 'filemover', 'accountcreator'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } njdp1s329eo72gk6icz9vw4ne954umh 28395 28394 2014-11-12T19:06:56Z w>Cenarium 0 restoring Mr. Stradivarius' edit since testing is OK and categories are ready 28395 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, accountcreator = {'templateeditor'}, autoconfirmed = {'reviewer', 'filemover', 'accountcreator'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 4u1nupyaek5tdfq2secpxnch19w5nzy 28396 28395 2015-01-06T22:21:00Z w>Jackmcbarn 0 - accountcreator 28396 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } tnw80riyb1pljsdzsta8zbb65qd461k 28397 28396 2015-03-23T13:52:43Z w>Mr. Stradivarius 0 change the padlock positions table to a padlock indicator names table for the transition to [[mw:Help:Page status indicators|page status indicators]] 28397 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } t87llthx48vljv83e1li1y93hix00td 28398 28397 2015-03-23T14:02:17Z w>Mr. Stradivarius 0 undo for now - the code looks good, but we will need to change everything over at the same time to avoid it looking like a giant mess 28398 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock positions -------------------------------------------------------------------------------- -- This table provides the data for the "right" CSS property for small padlock -- icons, which determines where the icon appears on the top bar among the other -- top icons. The data is stored by protection action. If no value is found for -- the action, the default field is used. padlockPositions = { autoreview = '85px', default = '55px' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } tnw80riyb1pljsdzsta8zbb65qd461k 28399 28398 2015-03-27T00:07:12Z w>Mr. Stradivarius 0 switch to the new version using <indicator> tags 28399 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } t87llthx48vljv83e1li1y93hix00td 28400 28399 2015-09-06T08:46:37Z w>Mr. Stradivarius 0 split categories per protected edit request by [[User:Alakzi]] and [[Wikipedia:Categories for discussion/Log/2015 August 25#Category:Wikipedia protected templates]] 28400 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } po9k4yygknpm12zwo8uq5jrmv2hualu 28401 28400 2015-09-11T20:31:58Z w>Ymblanter 0 Changed protection level of Module:Protection banner/config: [[WP:High-risk templates|High-risk Lua module]]: RFPP request ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)) 28400 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock-red.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } po9k4yygknpm12zwo8uq5jrmv2hualu 28402 28401 2016-01-13T13:36:45Z w>MSGJ 0 replace red with gold, per changes on policy page 28402 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, and autoreview subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } } }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, and autoreview subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and proteciton level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, and autoreview subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. The arguments cannot be overwritten by the -- user. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 4agd25rld2crv31v4er3gxx3o3nt2te 28403 28402 2016-03-03T13:09:49Z w>Mr. Stradivarius 0 add support for upload protection 28403 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Protected images', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } h1cbzwoamg7rj82qrd5tij7lbempfqk 28404 28403 2016-04-30T02:45:00Z w>Fayenatic london 0 rename category to Wikipedia fully-protected files, see [[Wikipedia:Categories_for_discussion/Log/2016_March_9#Category:Protected_images]] 28404 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Protected main page images', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Protected project pages', ['all|talk|all|sysop|edit'] = 'Protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 7p28ituxq3kouvoipwc50gpkkj65py0 28405 28404 2016-05-02T20:18:30Z w>Fayenatic london 0 rename categories per [[WP:CFDS]] 28405 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page images', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected images', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 84h024muu7bhv4u0p68xegnd0xa18xk 28406 28405 2016-05-02T20:45:40Z w>Fayenatic london 0 images -> files 28406 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy.', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests.', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes.', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]].', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation.', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version.', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]].', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules.', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user.', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]].', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title.', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]].' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } kxarlj0ctyf1x3ozy4vc4o7x85s5mrc 28407 28406 2016-06-20T14:41:07Z w>MSGJ 0 remove some periods and add wikilink, per request of [[User:Voidxor]] 28407 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]' }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } pj1vz79fivlrs9maq1sh0gz5cgt3dhv 28408 28407 2016-08-23T06:47:03Z w>Mr. Stradivarius 0 add extended confirmed protection banners per protected edit request by [[User:Andy M. Wang]] 28408 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' .. ' under extended confirmed editing restrictions', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-expiry'] = 'Wikipedia protected pages without expiry', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } ajtkvwcmv2z0wxi26reipeklerkkojm 28409 28408 2016-09-29T18:34:07Z w>Cenarium 0 rmv [[category:Wikipedia protected pages without expiry]], expiry no longer needed 28409 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPIRY} - the protection expiry date in the format DD Month YYYY. If -- protection is indefinite or is not set, this is the blank string. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' .. ' under extended confirmed editing restrictions', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {expiry = 'indef', small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } rvw8vobjgnbv339ezrn993wvdat60wz 28410 28409 2016-09-29T18:37:39Z w>Cenarium 0 remove expiry param 28410 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' .. ' under extended confirmed editing restrictions', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } kdvyvajraeyocb313hmyu5g1gpbhk1e 28411 28410 2017-03-22T17:01:07Z w>Yaris678 0 Try new tooltip ecp 28411 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } io5qxrr9nbohomty22asvqjk4s1dn4t 28412 28411 2017-03-26T16:11:00Z w>Jo-Jo Eumerus 0 Per talk page request 28412 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to publication', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to publication', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } rpew0cjewf4fu1vzcgax7fts2soe3i3 28413 28412 2017-04-21T09:32:57Z w>Yaris678 0 Let's not get into whether and when we are publishing. Existing consensus at [[:Template:Protection table]] is "go live" for a very short description... but we have space here to be even more specific 28413 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to becoming visible to unregistered users', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } g3n16lqu6gf1ld30xbaqxxwq3e4n8ka 28414 28413 2018-01-08T20:15:25Z w>Redrose64 0 update following cat rename, see [[Wikipedia:Categories for discussion/Log/2017 December 10#Category:Wikipedia pending changes protected pages (level 1)]] 28414 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to becoming visible to unregistered users', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } fn8efrw7womz69ee21la2d38zsp7fy5 28415 28414 2018-01-27T02:46:16Z w>BrownHairedGirl 0 protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', // per [[Wikipedia:Categories_for_discussion/Log/2018_January_5#Category:Wikipedia_protected_pages]] 28415 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to becoming visible to unregistered users', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } hhzqd28fj5olzin4eeygno4totrmfh7 28416 28415 2018-06-04T21:26:24Z w>Swarm 0 Changed protection level for "[[Module:Protection banner/config]]": [[WP:High-risk templates|High-risk Lua module]]: restoring template editor access per RfPP request ([Edit=Require template editor access] (indefinite) [Move=Require template editor access] (indefinite)) 28415 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to becoming visible to unregistered users', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } hhzqd28fj5olzin4eeygno4totrmfh7 28417 28416 2018-06-07T15:55:40Z w>SMcCandlish 0 This usage of "given that" is confusing and non-idiomatic in some English dialects, but a simple "if" works in all of them. 28417 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to becoming visible to unregistered users', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } rws38o0t9lndqgh42vqj1de259tmqqo 28418 28417 2018-10-13T21:56:22Z w>Redrose64 0 [[Template:Pp-pc1]] was moved to [[Template:Pp-pc]] today, and that has put over 2000 pages into [[Category:Wikipedia pages with incorrect protection templates]] - the same pages should display the white padlock, but no longer do so 28418 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to becoming visible to unregistered users', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } o4bi0twiem9xvixhl3c7xrjvr8baye7 28419 28418 2018-10-15T18:41:52Z w>Writ Keeper 0 typo in extended protection blurb 28419 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to becoming visible to unregistered users', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } e7ry0yvy9hvssqijlqgrujvz9v3rew4 28420 28419 2018-10-31T16:05:57Z w>Amorymeltzer 0 Specify time of expiration in addition to date — [[Special:Permalink/864175467#Date but no time is misleading|suggested on talk]], seems to work and is reasonable 28420 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review prior to becoming visible to unregistered users', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[Wikipedia:Reviewing|reviewers]] or' .. ' [[Wikipedia:Administrators|administrators]] are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'Wikipedia:Protection policy#pc1', reviewer = 'Wikipedia:Protection policy#pc2' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|all|all|reviewer|autoreview'] = 'Wikipedia pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" g:i a e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } ip8xnb9oto593qsbhi3t67pws3sufjc 28421 28420 2018-10-31T19:21:33Z w>Amorymeltzer 0 Remove references to Pending Changes level 2, normalize PC1 as PC 28421 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { default = 'Padlock-silver-light.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" g:i a e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } jcunz0e78v4ighkh1sjqc51yeo07ust 28422 28421 2018-11-13T02:19:22Z w>Bellezzasolo 0 Update protection images per [[Special:Diff/868572665|this edit request]] by [[User:ProgrammingGeek]] (consensus at RfC) 28422 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" g:i a e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 34ii7e15pv5gik19x5gp1ohh24leak0 28423 28422 2018-11-13T04:04:47Z w>Bellezzasolo 0 Undid revision 868575645 by [[Special:Contributions/Bellezzasolo|Bellezzasolo]] ([[User talk:Bellezzasolo|talk]]) Hold this while images get protected 28423 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Padlock-silver-light.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { default = 'Padlock-silver-light.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" g:i a e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } jcunz0e78v4ighkh1sjqc51yeo07ust 28424 28423 2018-11-13T12:21:51Z w>Bellezzasolo 0 Undid revision 868586586 by [[Special:Contributions/Bellezzasolo|Bellezzasolo]] ([[User talk:Bellezzasolo|talk]]) protected and ready to go 28424 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully-protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" g:i a e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 34ii7e15pv5gik19x5gp1ohh24leak0 28425 28424 2018-12-09T11:21:56Z w>Timrollpickering 0 /* top */per [[WP:CFDS]], replaced: Wikipedia fully-protected templates → Wikipedia fully protected templates (2) 28425 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" g:i a e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 7byu2nxrybjck0j4gbhrcuq3kf4u2cg 28426 28425 2018-12-13T11:58:25Z w>Amorymeltzer 0 Use 24hour, no timezone; noted at [[Special:PermaLink/873423420#Currently_disabled:_two_issues|VPT]] and [[Special:Permalink/873480034#Time format|talkpage]] 28426 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" G:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } b6zfjtozdj9owgceuftwwo73uycipsu 28427 28426 2018-12-14T11:29:08Z w>Galobtter 0 use zero padded time in UTC 28427 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } il700bux0nbfqgg8o4yzq26kh9zy46y 28428 28427 2019-02-18T11:08:01Z w>Mz7 0 implement [[Special:Diff/883910101|sandboxed]] change: make extended confirmed protectionBlurb more concise and shift explanation about ArbCom to the explanationBurb 28428 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } c5gvdtahmamzwokp5mf8rdgs025cfl8 28429 28428 2019-02-19T09:55:48Z w>Mz7 0 change "IP editors" → "unregistered editors" for clarity 28429 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 2v9tgri7evhqu00earv6p8jaw0ilbdt 28430 28429 2019-10-06T17:07:57Z w>Black Falcon 0 distinguish full and semi-protection 28430 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } irc377lwqveuq9dqrga9qduokfcsd3y 28431 28430 2019-10-14T16:11:48Z w>Trialpears 0 Implementing [[Wikipedia:Categories for discussion/Log/2019 October 6#Category:Wikipedia pages under 30-500 editing restriction]] 28431 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 68szndvzxbukd15o7m1vtgro3xw0a80 28432 28431 2019-10-30T13:33:23Z w>Trialpears 0 Pp-30-500 changed name 28432 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } rsipy7cew0tk7nu4934i3g81vvs4vyx 28433 28432 2020-02-09T10:06:16Z w>DannyS712 0 people -> persons, per edit request 28433 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } scj9exx3uf3stq00uy4gpnlbwru3gox 28434 28413 2017-09-15T13:15:07Z w>MarcoAurelio 0 28434 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { autoconfirmed = { alt = 'Page protected with pending changes level 1', tooltip = 'All edits by unregistered and new users are subject to review', image = 'Padlock-silver-light.svg' }, default = { alt = 'Page protected with pending changes level 2', tooltip = 'All edits by users who are not reviewers or administrators are' .. ' subject to review', image = 'Padlock-orange.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[w:Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[w:Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living people', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Special:MyLanguage/Legal#DMCA|Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Special:MyLanguage/Office actions|Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}' .. ' under extended confirmed editing restrictions', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Special:MyLanguage/Help:Protection|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Special:MyLanguage/Main Page|Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Special:MyLanguage/Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Special:MyLanguage/Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[Special:MyLanguage/Neutral point of view|Neutral Point of View]] and [[w:en:WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', }, sock = { description = 'For pages protected due to' .. ' [[Special:MyLanguage/Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Sock puppetry|sock puppets]] of' .. ' [[Special:MyLanguage/Blocked user|blocked]] or' .. ' [[Special:MyLanguage/Banned user|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[w:en:Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Special:MyLanguage/Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[w:en:Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Special:MyLanguage/Meta:Administrators|administrator]] or' .. ' [[w:en:Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Special:MyLanguage/Consensus|consensus]]. You can also' .. ' [[Meta:Requests for help from a sysop or bureaucrat|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Meta:Requests for help from a sysop or bureaucrat' .. '|request an edit]],' .. ' [[Meta:Requests for help from a sysop or bureaucrat' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Meta:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Meta:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-olive.svg' }, vandalism = { description = 'For pages protected against' .. ' [[w:en:Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Special:MyLanguage/Newly' .. ' registered user|new]] or [[Special:MyLanguage/Unregistered' .. ' user|unregistered]] users is currently [[Special:MyLanguage/Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} as a result of' .. ' [[Special:MyLanguage/Arbitration Committee|ArbCom]] enforcement or meets the' .. ' [[w:en:Wikipedia:Protection policy#extended|criteria for community use]]', }, move = { default = 'This ${PAGETYPE} is currently [[Special:MyLanguage/Help:Protection|protected]]' .. ' from [[Special:MyLanguage/Help:Moving a page|page moves]]' }, autoreview = { autoconfirmed = 'All edits made to this ${PAGETYPE} by' .. ' [[Special:MyLanguage/Newly registered users|new]] or' .. ' [[Special:MyLanguage/Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Flagged Revisions|subject to review]]', default = 'All edits made to this ${PAGETYPE} by users who are not' .. ' [[w:en:Wikipedia:Reviewing|reviewers]] or' .. ' [[Special:MyLanguage/Meta:Administrators|administrators]] are currently' .. ' [[Flagged Revisions|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Meta:Requests for help from a sysop or bureaucrat' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Meta:Requests for help from a sysop or bureaucrat' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all IP editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[w:en:Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, given that semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for unconversial changes supported by' .. ' [[Special:MyLanguage/Consensus|consensus]].' }, default = { subject = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Special:MyLanguage/Meta:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Special:MyLanguage/Consensus' .. '|consensus]]. You may also [[Meta:Requests for help from a sysop or bureaucrat' .. '|request]] that this page be unprotected.', default = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Meta:Requests for help from a sysop or bureaucrat|request an' .. ' edit]] to this page, or [[Meta:Requests for help from a sysop or bureaucrat' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Meta:Babel]]. You can also' .. ' [[Meta:Requests for help from a sysop or bureaucrat|request]] that the page be' .. ' unprotected.', default = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Meta:Babel]]. You can also' .. ' [[Meta:Requests for help from a sysop or bureaucrat|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { reviewer = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} will not be visible to readers' .. ' until they are accepted by a reviewer or an administrator.' .. ' To avoid the need for your edits to be reviewed, you may' .. ' [[Meta:Requests for help from a sysop or bureaucrat' .. '|request unprotection]]. Experienced editors may also' .. ' request the [[w:en:Wikipedia:Reviewing|reviewer user right]].', default = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Meta:Requests for help from a sysop or bureaucrat' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Template:Edit Protected|protected edit request]], or you' .. ' can [[Meta:Requests for help from a sysop or bureaucrat|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', templateeditor = 'Padlock-pink.svg', extendedconfirmed = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-olive.svg', }, autoreview = { autoconfirmed = 'Padlock-silver-light.svg', default = 'Padlock-orange.svg' }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'w:en:Wikipedia:Protection policy#full', templateeditor = 'w:en:Wikipedia:Protection policy#template', extendedconfirmed = 'w:en:Wikipedia:Protection policy#extended', autoconfirmed = 'w:en:Wikipedia:Protection policy#semi' }, move = { default = 'w:en:Wikipedia:Protection policy#move' }, autoreview = { autoconfirmed = 'w:en:Wikipedia:Protection policy#pc1', reviewer = 'w:en:Wikipedia:Protection policy#pc2' }, upload = { default = 'w:en:Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Protected', ['all|all|office|all|all'] = 'Office-protected', ['all|all|reset|all|all'] = 'Office-protected', ['all|all|dmca|all|all'] = 'Office-protected', ['all|all|mainpage|all|all'] = 'fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'pages under 30-500 editing restriction', ['all|all|ecp|extendedconfirmed|all'] = 'pages under 30-500 editing restriction', ['all|template|all|all|edit'] = 'fully-protected templates', ['all|all|all|autoconfirmed|edit'] = 'semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'indefinitely semi-protected', ['all|all|blp|autoconfirmed|edit'] = 'indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'template-protected templates', ['all|all|blp|sysop|edit'] = 'indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'pages protected against vandalism', ['all|category|all|sysop|edit'] = 'protected categories', ['all|file|all|sysop|edit'] = 'fully-protected files', ['all|project|all|sysop|edit'] = 'fully-protected project pages', ['all|talk|all|sysop|edit'] = 'fully-protected talk pages', ['all|template|all|sysop|edit'] = 'fully-protected templates', ['all|user|all|sysop|edit'] = 'protected user and user talk pages', ['all|module|all|all|edit'] = 'fully-protected modules', ['all|module|all|templateeditor|edit'] = 'template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'semi-protected modules', ['all|all|all|sysop|move'] = 'move-protected', ['indef|all|all|sysop|move'] = 'indefinitely move-protected', ['all|all|dispute|sysop|move'] = 'pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'move-protected portals', ['all|portal|all|sysop|move'] = 'move-protected portals', ['all|project|all|sysop|move'] = 'move-protected project pages', ['all|talk|all|sysop|move'] = 'move-protected talk pages', ['all|template|all|sysop|move'] = 'move-protected templates', ['all|user|all|sysop|move'] = 'move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'pending changes protected pages (level 1)', ['all|all|all|reviewer|autoreview'] = 'pending changes protected pages (level 2)', ['all|file|all|all|upload'] = 'upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-30-500'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-pc2'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[w:en:Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Special:MyLanguage/Meta:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Special:MyLanguage/Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Pages with incorrect protection templates', ['tracking-category-template'] = 'Template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 1r00m060lhvr7bfkazmv7okjaa3cvpw 28435 28433 2020-04-01T06:12:47Z w>MusikAnimal 0 1 revision imported 28433 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } scj9exx3uf3stq00uy4gpnlbwru3gox 28436 28435 2020-08-29T12:38:28Z w>ProcrastinatingReader 0 merge from sandbox; categorise extended-confirmed templates separately 28436 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } cbbgs21oljuf1fev72tjcjzr3c1wtso 28437 28436 2020-08-30T14:38:18Z w>Mr. Stradivarius 0 change category name from [[:Category:Wikipedia extended-confirmed protected templates]] to [[:Category:Wikipedia extended-confirmed-protected templates]] per talk 28437 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } tsjw0kwy7tfddnzw9kg8pmamgo0ykx2 28438 28437 2020-09-06T00:07:52Z w>ProcrastinatingReader 0 fix broken testcase & improper categorisation, per talk 28438 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 5ltdht3qen29flk1vw801ukkdsv9cxq 28439 28438 2021-07-16T12:00:11Z w>ProcrastinatingReader 0 make pp-move show category only 28439 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } ksre43f5mpii72381u5ajhgs8518kyr 28440 28439 2021-07-28T10:04:57Z w>ProcrastinatingReader 0 remove dupe 28440 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 504rdzt1403pfg5dzgyxgdybcqace4a 28441 28440 2021-11-04T01:02:09Z w>Elli 0 from [[Special:Permalink/1053387039|sandbox]]: not necessary to catch TPE'd non-templates as an error when it can be done as part of the normal workflow 28441 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 7dnwkiex2p6rvxapspvhhpl8zg9xq9g 28442 28441 2022-02-03T23:49:55Z w>Andrybak 0 add categorization into [[:Category:Wikipedia extended-confirmed-protected modules]] per [[Special:Diff/1069761256|request]] 28442 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is extended-confirmed protected', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } eeb6sgpzkp24z3uln44ko8rah6nhotf 28443 28442 2022-10-06T04:15:13Z w>Paine Ellsworth 0 per edit request at [[Module talk:Protection banner#Tooltip/title does not match the actual protection level]] - fix appearance of protection level 28443 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully-protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully-protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully-protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully-protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully-protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } ahhe4ldlafnhr9o5b3ltlif05kw0saj 28444 28443 2023-05-08T11:41:01Z w>Fayenatic london 0 Update categories from "fully-protected" to "fully protected", removing hyphen, per valid request at [[WP:CFDS]] 28444 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } ixbvsupazcc7jogy6wdd8knifx1xwnz 28445 28444 2024-03-01T12:45:46Z w>SilverLocust 0 Fix for [[Template talk:Db-a1]] and similar template-protected non-template redirects being miscategorized into [[Category:Wikipedia fully protected pages]]. 28445 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|move'] = 'Wikipedia template-protected pages other than templates and modules', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } bwdq6s0o76ylir1k2sdre20yoyvjw2e 28446 28445 2024-10-23T18:52:32Z w>Aidan9382 0 Make office padlocks link to the office section of the protection policy 28446 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|move'] = 'Wikipedia template-protected pages other than templates and modules', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } c4z1ehxgtjgd1hicn104j5krw678qfy 28447 28446 2024-10-31T23:04:32Z w>Aidan9382 0 Fix |small= (and other args) not working post-page move 28447 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|move'] = 'Wikipedia template-protected pages other than templates and modules', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 2pm461z7sd4mfkppwz2sfpogjevrtyz 28448 28447 2025-01-13T14:33:44Z w>Jonesey95 0 fix alt text to match name of protection level 28448 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-confirmed-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|move'] = 'Wikipedia template-protected pages other than templates and modules', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 4j9s25hqt968zd5fewsvtkzzg34omaf 28449 28448 2025-12-30T02:00:55Z en>Codename Noreste 0 147 revisions imported from [[:w:Module:Protection_banner/config]]: Required for [[Module:Documentation]]. 28448 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { blp = { description = 'For pages protected to promote compliance with the' .. ' [[Wikipedia:Biographies of living persons' .. '|biographies of living persons]] policy', text = '${INTROFRAGMENT} to promote compliance with' .. ' [[Wikipedia:Biographies of living persons' .. "|Wikipedia's&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;people]].', tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on' .. ' biographies of living persons', }, dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to [[Digital Millennium Copyright Act]] takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].' .. ' Standard Wikipedia policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for edits to a protected page' .. '|request an edit]],' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikipedia:Vandalism#Page-move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access' .. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered' .. ' users|unregistered]] users is currently [[Help:Protection|disabled]]', extendedconfirmed = 'This ${PAGETYPE} is currently under extended confirmed protection', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { default = 'All edits made to this ${PAGETYPE} by' .. ' [[Wikipedia:User access levels#New users|new]] or' .. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]' .. ' users are currently' .. ' [[Wikipedia:Pending changes|subject to review]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]]. You may also [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|request]] that this page be unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Requests for page' .. ' protection#Current requests for edits to a protected page|request an' .. ' edit]] to this page, or [[Wikipedia:Requests for' .. ' page protection#Current requests for reduction in protection level' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikipedia:Requested moves]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikipedia:Requests for page protection' .. '#Current requests for reduction in protection level' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' [[Wikipedia:Edit requests|protected edit request]], or you' .. ' can [[Wikipedia:Requests for page protection|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', templateeditor = 'template-protected', extendedconfirmed = 'extended-confirmed-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', templateeditor = 'Template-protection-shackle.svg', extendedconfirmed = 'Extended-protection-shackle.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', }, autoreview = { default = 'Pending-protection-shackle.svg' }, upload = { default = 'Upload-protection-shackle.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikipedia:Protection policy#full', templateeditor = 'Wikipedia:Protection policy#template', extendedconfirmed = 'Wikipedia:Protection policy#extended', autoconfirmed = 'Wikipedia:Protection policy#semi' }, move = { default = 'Wikipedia:Protection policy#move' }, autoreview = { default = 'Wikipedia:Protection policy#pending' }, upload = { default = 'Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikipedia fully protected pages', ['all|all|office|all|all'] = 'Wikipedia Office-protected pages', ['all|all|reset|all|all'] = 'Wikipedia Office-protected pages', ['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikipedia fully protected main page files', ['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages', ['all|template|all|all|edit'] = 'Wikipedia fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages', ['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people', ['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people', ['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages', ['all|all|all|templateeditor|move'] = 'Wikipedia template-protected pages other than templates and modules', ['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules', ['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates', ['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates ['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people', ['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people', ['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories', ['all|file|all|sysop|edit'] = 'Wikipedia fully protected files', ['all|project|all|sysop|edit'] = 'Wikipedia fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikipedia fully protected talk pages', ['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates', ['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates', ['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikipedia fully protected modules', ['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules', ['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules', ['all|all|all|sysop|move'] = 'Wikipedia move-protected pages', ['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals', ['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikipedia move-protected templates', ['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages', ['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages', ['all|file|all|all|upload'] = 'Wikipedia upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, reviewer = {'sysop'}, filemover = {'sysop'}, templateeditor = {'sysop'}, extendedconfirmed = {'sysop'}, autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates', ['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } 4j9s25hqt968zd5fewsvtkzzg34omaf 28450 28449 2025-12-30T02:31:20Z en>Codename Noreste 0 Localizing for Wikiquote. 28450 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[:w:Wikipedia:Office actions|Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', link = ':w:Wikipedia:Protection policy#office', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[:w:Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[:w:Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = ':w:Wikipedia:Protection policy#office', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WQ:NPOV|Neutral Point of View]] and [[WQ:VERIFY|Verifiability]].' .. ' Standard Wikiquote policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikiquote:Administrators\' noticeboard|request an edit]],' .. ' [[Wikiquote:Administrators\' noticeboard|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wkiquote:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikiquote:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-green.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism|page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[:w:Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikiquote:Users|new]]' .. 'or [[Wikipedia:User access levels#Unregistered users|unregistered]] users is currently [[:w:Help:Protection|disabled]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikiquote:Administrators\' noticeboard' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikiquote:Administrators\' noticeboard' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit' .. '|uncontroversial]] or supported by consensus.' .. 'You may also [[Wikiquote:Administrators\' noticeboard' .. '|request]] that this page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikiquote:Administrators\' noticeboard|request an' .. ' edit]] to this page, or [[Wikiquote:Administrators\' noticeboard' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE}. You can also' .. ' [[Wikiquote:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. You can also' .. ' [[Wikiquote:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikiquote:Administrators\' noticeboard|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' protected edit request, or you' .. ' can [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-green.svg', }, autoreview = { }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = ':w:Wikipedia:Protection policy#full', autoconfirmed = ':w:Wikipedia:Protection policy#semi' }, move = { default = ':w:Wikipedia:Protection policy#move' }, autoreview = { default = ':w:Wikipedia:Protection policy#pending' }, upload = { default = ':w:Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikiquote fully protected pages', ['all|all|office|all|all'] = 'Wikiquote Office-protected pages', ['all|all|reset|all|all'] = 'Wikiquote Office-protected pages', ['all|all|dmca|all|all'] = 'Wikiquote Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikiquote fully protected main page files', ['all|template|all|all|edit'] = 'Wikiquote fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikiquote semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikiquote indefinitely semi-protected pages', ['all|all|dispute|autoconfirmed|edit'] = 'Wikiquote pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikiquote pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikiquote pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikiquote semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikiquote semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikiquote semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikiquote semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikiquote semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikiquote semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikiquote semi-protected user and user talk pages', ['all|all|dispute|sysop|edit'] = 'Wikiquote pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikiquote pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikiquote pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikiquote fully protected categories', ['all|file|all|sysop|edit'] = 'Wikiquote fully protected files', ['all|project|all|sysop|edit'] = 'Wikiquote fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikiquote fully protected talk pages', ['all|template|all|sysop|edit'] = 'Wikiquote fully protected templates', ['all|user|all|sysop|edit'] = 'Wikiquote fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikiquote fully protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikiquote semi-protected modules', ['all|all|all|sysop|move'] = 'Wikiquote move-protected pages', ['indef|all|all|sysop|move'] = 'Wikiquote indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikiquote pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikiquote pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikiquote move-protected portals', ['all|project|all|sysop|move'] = 'Wikiquote move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikiquote move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikiquote move-protected templates', ['all|user|all|sysop|move'] = 'Wikiquote move-protected user and user talk pages', ['all|file|all|all|upload'] = 'Wikiquote upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, autoconfirmed = {'sysop'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[:w:Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikiquote pages with incorrect protection templates', ['tracking-category-template'] = 'Wikiquote template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } c1vpbv15tzl576nxesfsluev8r4iaop 28451 28450 2025-12-30T02:32:00Z en>Codename Noreste 0 Using padlock instead of full-protection-shackle. 28451 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[:w:Wikipedia:Office actions|Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', link = ':w:Wikipedia:Protection policy#office', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[:w:Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently' .. ' [[:w:Wikipedia:This page is protected|protected]] from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = ':w:Wikipedia:Protection policy#office', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WQ:NPOV|Neutral Point of View]] and [[WQ:VERIFY|Verifiability]].' .. ' Standard Wikiquote policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikipedia:Protection policy#office', }, sock = { description = 'For pages protected due to' .. ' [[Wikipedia:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of' .. ' [[Wikipedia:Blocking policy|blocked]] or' .. ' [[Wikipedia:Banning policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For [[Wikipedia:High-risk templates|high-risk]]' .. ' templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is [[Wikipedia:High-risk templates|high-risk]].', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikipedia:Administrators|administrator]] or' .. ' [[Wikipedia:Template editor|template editor]] to make an edit if' .. ' it is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by' .. ' [[Wikipedia:Consensus|consensus]]. You can also' .. ' [[Wikipedia:Requests for page protection|request]] that the page be' .. ' unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikiquote:Administrators\' noticeboard|request an edit]],' .. ' [[Wikiquote:Administrators\' noticeboard|request unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wkiquote:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikiquote:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-green.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism|page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[:w:Help:Protection|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikiquote:Users|new]]' .. 'or [[Wikipedia:User access levels#Unregistered users|unregistered]] users is currently [[:w:Help:Protection|disabled]]', }, move = { default = 'This ${PAGETYPE} is currently [[Help:Protection|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, autoreview = { }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikiquote:Administrators\' noticeboard' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikiquote:Administrators\' noticeboard' .. '|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, extendedconfirmed = { default = 'Extended confirmed protection prevents edits from all unregistered editors' .. ' and registered users with fewer than 30 days tenure and 500 edits.' .. ' The [[Wikipedia:Protection policy#extended|policy on community use]]' .. ' specifies that extended confirmed protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Extended confirmed protection may also be applied to enforce' .. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by' .. ' [[Wikipedia:Consensus|consensus]].' }, default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit' .. '|uncontroversial]] or supported by consensus.' .. 'You may also [[Wikiquote:Administrators\' noticeboard' .. '|request]] that this page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikiquote:Administrators\' noticeboard|request an' .. ' edit]] to this page, or [[Wikiquote:Administrators\' noticeboard' .. '|ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE}. You can also' .. ' [[Wikiquote:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.', default = 'See the [[Wikipedia:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. You can also' .. ' [[Wikiquote:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.' } }, autoreview = { default = { default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Edits to this ${PAGETYPE} by new and unregistered users' .. ' will not be visible to readers until they are accepted by' .. ' a reviewer. To avoid the need for your edits to be' .. ' reviewed, you may' .. ' [[Wikiquote:Administrators\' noticeboard|request unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].' }, }, upload = { default = { default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but new versions of the file' .. ' cannot be uploaded until it is unprotected. You can' .. ' request that a new version be uploaded by using a' .. ' protected edit request, or you' .. ' can [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that the file be unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' }, autoreview = { }, upload = { default = 'upload-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-green.svg', }, autoreview = { }, upload = { default = 'Padlock-purple.svg' } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = ':w:Wikipedia:Protection policy#full', autoconfirmed = ':w:Wikipedia:Protection policy#semi' }, move = { default = ':w:Wikipedia:Protection policy#move' }, autoreview = { default = ':w:Wikipedia:Protection policy#pending' }, upload = { default = ':w:Wikipedia:Protection policy#upload' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikiquote fully protected pages', ['all|all|office|all|all'] = 'Wikiquote Office-protected pages', ['all|all|reset|all|all'] = 'Wikiquote Office-protected pages', ['all|all|dmca|all|all'] = 'Wikiquote Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikiquote fully protected main page files', ['all|template|all|all|edit'] = 'Wikiquote fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikiquote semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikiquote indefinitely semi-protected pages', ['all|all|dispute|autoconfirmed|edit'] = 'Wikiquote pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikiquote pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikiquote pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikiquote semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikiquote semi-protected files', ['all|portal|all|autoconfirmed|edit'] = 'Wikiquote semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikiquote semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikiquote semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikiquote semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikiquote semi-protected user and user talk pages', ['all|all|dispute|sysop|edit'] = 'Wikiquote pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikiquote pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikiquote pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikiquote fully protected categories', ['all|file|all|sysop|edit'] = 'Wikiquote fully protected files', ['all|project|all|sysop|edit'] = 'Wikiquote fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikiquote fully protected talk pages', ['all|template|all|sysop|edit'] = 'Wikiquote fully protected templates', ['all|user|all|sysop|edit'] = 'Wikiquote fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikiquote fully protected modules', ['all|module|all|autoconfirmed|edit'] = 'Wikiquote semi-protected modules', ['all|all|all|sysop|move'] = 'Wikiquote move-protected pages', ['indef|all|all|sysop|move'] = 'Wikiquote indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikiquote pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikiquote pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikiquote move-protected portals', ['all|project|all|sysop|move'] = 'Wikiquote move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikiquote move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikiquote move-protected templates', ['all|user|all|sysop|move'] = 'Wikiquote move-protected user and user talk pages', ['all|file|all|all|upload'] = 'Wikiquote upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, autoconfirmed = {'sysop'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit#When to mark an edit as a minor edit' .. '|uncontroversial]] or supported by [[:w:Wikipedia:Consensus' .. '|consensus]].', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikiquote pages with incorrect protection templates', ['tracking-category-template'] = 'Wikiquote template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } lzig2383et5228w42g4c8h403f5dbev 28452 28451 2026-01-22T20:10:57Z en>Codename Noreste 0 Updating. 28452 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[:w:Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', link = 'Wikiquote:Protection policy#Office actions', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[:w:Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently protected from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', link = 'Wikiquote:Protection policy#Office actions', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WQ:NPOV|Neutral Point of View]] and [[WQ:VERIFY|Verifiability]].' .. ' Standard Wikiquote policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', link = 'Wikiquote:Protection policy#Office actions', }, sock = { description = 'For pages protected due to' .. ' [[Wikiquote:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikiquote:Sock puppetry|sock puppets]] of' .. ' [[Wikiquote:Blocking policy|blocked]] or' .. ' [[Wikiquote:Blocking policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For high-risk templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is high-risk.', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if' .. ' it is [[Help:Minor edit|uncontroversial]] or supported by' .. ' consensus. You can also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that the page be unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikiquote:Administrators\' noticeboard|request an edit or unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-green.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism#Page move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikiquote:User' .. ' groups#New users|new]] or [[Wikiquote:User groups#Unregistered' .. ' users|unregistered]] users is currently [[Wikiquote:Protection policy|disabled]]', autopatrol = 'This ${PAGETYPE} is currently under autopatroller protection', }, move = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, autopatrol = { default = 'The [[Wikiquote:Protection policy#Autopatroller protection|policy on community use]]' .. ' specifies that autopatroller protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by consensus.' }, default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.' .. ' You may also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that this page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Administrators\' noticeboard' .. ' |request an edit or ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikiquote:Administrators\' noticeboard]].' .. ' You can also [[Wikiquote:Administrators\' noticeboard|' .. ' request]] that the page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. ' protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikiquote:Administrators\' noticeboard]]. You can also' .. ' [[Wikipedia:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', autopatrol = 'autopatroller-protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', autopatrol = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-green.svg', } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikiquote:Protection policy#Full protection', autopatrol = 'Wikiquote:Protection policy#Autopatroller protection', autoconfirmed = 'Wikiquote:Protection policy#Semi-protection' }, move = { default = 'Wikiquote:Protection policy#Move protection' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikiquote fully protected pages', ['all|all|office|all|all'] = 'Wikiquote Office-protected pages', ['all|all|reset|all|all'] = 'Wikiquote Office-protected pages', ['all|all|dmca|all|all'] = 'Wikiquote Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikiquote fully protected main page files', ['all|template|all|all|edit'] = 'Wikiquote fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikiquote semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikiquote indefinitely semi-protected pages', ['all|all|dispute|autoconfirmed|edit'] = 'Wikiquote pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikiquote pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikiquote pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikiquote semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikiquote semi-protected files', ['all|module|all|autoconfirmed|edit'] = 'Wikiquote semi-protected modules', ['all|portal|all|autoconfirmed|edit'] = 'Wikiquote semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikiquote semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikiquote semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikiquote semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikiquote semi-protected user and user talk pages', -- move-protected templates ['all|all|all|autopatrol|edit'] = 'Wikiquote autopatroller protected pages', ['all|category|all|autopatrol|edit'] = 'Wikiquote autopatroller protected categories', ['all|file|all|autopatrol|edit'] = 'Wikiquote autopatroller protected files', ['all|module|all|autopatrol|edit'] = 'Wikiquote autopatroller protected modules', ['all|portal|all|autopatrol|edit'] = 'Wikiquote autopatroller protected portals', ['all|project|all|autopatrol|edit'] = 'Wikiquote autopatroller protected project pages', ['all|talk|all|autopatrol|edit'] = 'Wikiquote autopatroller protected talk pages', ['all|template|all|autopatrol|edit'] = 'Wikiquote autopatroller protected templates', ['all|user|all|autopatrol|edit'] = 'Wikiquote autopatroller protected user and user talk pages', -- move-protected templates ['all|all|dispute|sysop|edit'] = 'Wikiquote pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikiquote pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikiquote pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikiquote fully protected categories', ['all|file|all|sysop|edit'] = 'Wikiquote fully protected files', ['all|project|all|sysop|edit'] = 'Wikiquote fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikiquote fully protected talk pages', ['all|template|all|sysop|edit'] = 'Wikiquote fully protected templates', ['all|user|all|sysop|edit'] = 'Wikiquote fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikiquote fully protected modules', ['all|all|all|sysop|move'] = 'Wikiquote move-protected pages', ['indef|all|all|sysop|move'] = 'Wikiquote indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikiquote pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikiquote pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikiquote move-protected portals', ['all|project|all|sysop|move'] = 'Wikiquote move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikiquote move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikiquote move-protected templates', ['all|user|all|sysop|move'] = 'Wikiquote move-protected user and user talk pages', ['all|file|all|all|upload'] = 'Wikiquote upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, autopatrol = {'sysop'}, autoconfirmed = {'autopatrolled', 'patroller', 'sysop'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikiquote pages with incorrect protection templates', ['tracking-category-template'] = 'Wikiquote template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } n73dxi502kltogquks4ryx9qywisah7 28453 28452 2026-01-23T16:06:35Z en>Codename Noreste 0 For autopatroller protection, restore to the standard "protected" wording. 28453 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[:w:Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Padlock-black.svg', link = 'Wikiquote:Protection policy#Office actions', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[:w:Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently protected from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Padlock-black.svg', link = 'Wikiquote:Protection policy#Office actions', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WQ:NPOV|Neutral Point of View]] and [[WQ:VERIFY|Verifiability]].' .. ' Standard Wikiquote policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Padlock-black.svg', link = 'Wikiquote:Protection policy#Office actions', }, sock = { description = 'For pages protected due to' .. ' [[Wikiquote:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikiquote:Sock puppetry|sock puppets]] of' .. ' [[Wikiquote:Blocking policy|blocked]] or' .. ' [[Wikiquote:Blocking policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For high-risk templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is high-risk.', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if' .. ' it is [[Help:Minor edit|uncontroversial]] or supported by' .. ' consensus. You can also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that the page be unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikiquote:Administrators\' noticeboard|request an edit or unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Padlock-green.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism#Page move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikiquote:User' .. ' groups#New users|new]] or [[Wikiquote:User groups#Unregistered' .. ' users|unregistered]] users is currently [[Wikiquote:Protection policy|disabled]]', autopatrol = 'This ${PAGETYPE} is currently under autopatroller protection', }, move = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, autopatrol = { default = 'The [[Wikiquote:Protection policy#Autopatroller protection|policy on community use]]' .. ' specifies that autopatroller protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by consensus.' }, default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.' .. ' You may also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that this page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Administrators\' noticeboard' .. ' |request an edit or ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikiquote:Administrators\' noticeboard]].' .. ' You can also [[Wikiquote:Administrators\' noticeboard|' .. ' request]] that the page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. ' protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikiquote:Administrators\' noticeboard]]. You can also' .. ' [[Wikipedia:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Padlock.svg', autopatrol = 'Padlock-blue.svg', autoconfirmed = 'Padlock-silver.svg' }, move = { default = 'Padlock-green.svg', } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikiquote:Protection policy#Full protection', autopatrol = 'Wikiquote:Protection policy#Autopatroller protection', autoconfirmed = 'Wikiquote:Protection policy#Semi-protection' }, move = { default = 'Wikiquote:Protection policy#Move protection' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikiquote fully protected pages', ['all|all|office|all|all'] = 'Wikiquote Office-protected pages', ['all|all|reset|all|all'] = 'Wikiquote Office-protected pages', ['all|all|dmca|all|all'] = 'Wikiquote Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikiquote fully protected main page files', ['all|template|all|all|edit'] = 'Wikiquote fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikiquote semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikiquote indefinitely semi-protected pages', ['all|all|dispute|autoconfirmed|edit'] = 'Wikiquote pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikiquote pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikiquote pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikiquote semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikiquote semi-protected files', ['all|module|all|autoconfirmed|edit'] = 'Wikiquote semi-protected modules', ['all|portal|all|autoconfirmed|edit'] = 'Wikiquote semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikiquote semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikiquote semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikiquote semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikiquote semi-protected user and user talk pages', -- move-protected templates ['all|all|all|autopatrol|edit'] = 'Wikiquote autopatroller protected pages', ['all|category|all|autopatrol|edit'] = 'Wikiquote autopatroller protected categories', ['all|file|all|autopatrol|edit'] = 'Wikiquote autopatroller protected files', ['all|module|all|autopatrol|edit'] = 'Wikiquote autopatroller protected modules', ['all|portal|all|autopatrol|edit'] = 'Wikiquote autopatroller protected portals', ['all|project|all|autopatrol|edit'] = 'Wikiquote autopatroller protected project pages', ['all|talk|all|autopatrol|edit'] = 'Wikiquote autopatroller protected talk pages', ['all|template|all|autopatrol|edit'] = 'Wikiquote autopatroller protected templates', ['all|user|all|autopatrol|edit'] = 'Wikiquote autopatroller protected user and user talk pages', -- move-protected templates ['all|all|dispute|sysop|edit'] = 'Wikiquote pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikiquote pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikiquote pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikiquote fully protected categories', ['all|file|all|sysop|edit'] = 'Wikiquote fully protected files', ['all|project|all|sysop|edit'] = 'Wikiquote fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikiquote fully protected talk pages', ['all|template|all|sysop|edit'] = 'Wikiquote fully protected templates', ['all|user|all|sysop|edit'] = 'Wikiquote fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikiquote fully protected modules', ['all|all|all|sysop|move'] = 'Wikiquote move-protected pages', ['indef|all|all|sysop|move'] = 'Wikiquote indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikiquote pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikiquote pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikiquote move-protected portals', ['all|project|all|sysop|move'] = 'Wikiquote move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikiquote move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikiquote move-protected templates', ['all|user|all|sysop|move'] = 'Wikiquote move-protected user and user talk pages', ['all|file|all|all|upload'] = 'Wikiquote upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, autopatrol = {'sysop'}, autoconfirmed = {'autopatrolled', 'patroller', 'sysop'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikiquote pages with incorrect protection templates', ['tracking-category-template'] = 'Wikiquote template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } rtuuydx6y9c7o91l14xxzm6uhdd6elo 28454 28453 2026-04-10T14:25:52Z en>Codename Noreste 0 Updating the protection icons. 28454 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[:w:Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[:w:Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently protected from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WQ:NPOV|Neutral Point of View]] and [[WQ:VERIFY|Verifiability]].' .. ' Standard Wikiquote policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, sock = { description = 'For pages protected due to' .. ' [[Wikiquote:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikiquote:Sock puppetry|sock puppets]] of' .. ' [[Wikiquote:Blocking policy|blocked]] or' .. ' [[Wikiquote:Blocking policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For high-risk templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is high-risk.', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if' .. ' it is [[Help:Minor edit|uncontroversial]] or supported by' .. ' consensus. You can also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that the page be unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikiquote:Administrators\' noticeboard|request an edit or unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism#Page move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikiquote:User' .. ' groups#New users|new]] or [[Wikiquote:User groups#Unregistered' .. ' users|unregistered]] users is currently [[Wikiquote:Protection policy|disabled]]', autopatrol = 'This ${PAGETYPE} is currently under autopatroller protection', }, move = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, autopatrol = { default = 'The [[Wikiquote:Protection policy#Autopatroller protection|policy on community use]]' .. ' specifies that autopatroller protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by consensus.' }, default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.' .. ' You may also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that this page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Administrators\' noticeboard' .. ' |request an edit or ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikiquote:Administrators\' noticeboard]].' .. ' You can also [[Wikiquote:Administrators\' noticeboard|' .. ' request]] that the page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. ' protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikiquote:Administrators\' noticeboard]]. You can also' .. ' [[Wikipedia:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', autopatrol = 'Extended-protection-shackle-account-pro-plus.svg.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikiquote:Protection policy#Full protection', autopatrol = 'Wikiquote:Protection policy#Autopatroller protection', autoconfirmed = 'Wikiquote:Protection policy#Semi-protection' }, move = { default = 'Wikiquote:Protection policy#Move protection' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikiquote fully protected pages', ['all|all|office|all|all'] = 'Wikiquote Office-protected pages', ['all|all|reset|all|all'] = 'Wikiquote Office-protected pages', ['all|all|dmca|all|all'] = 'Wikiquote Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikiquote fully protected main page files', ['all|template|all|all|edit'] = 'Wikiquote fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikiquote semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikiquote indefinitely semi-protected pages', ['all|all|dispute|autoconfirmed|edit'] = 'Wikiquote pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikiquote pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikiquote pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikiquote semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikiquote semi-protected files', ['all|module|all|autoconfirmed|edit'] = 'Wikiquote semi-protected modules', ['all|portal|all|autoconfirmed|edit'] = 'Wikiquote semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikiquote semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikiquote semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikiquote semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikiquote semi-protected user and user talk pages', -- move-protected templates ['all|all|all|autopatrol|edit'] = 'Wikiquote autopatroller protected pages', ['all|category|all|autopatrol|edit'] = 'Wikiquote autopatroller protected categories', ['all|file|all|autopatrol|edit'] = 'Wikiquote autopatroller protected files', ['all|module|all|autopatrol|edit'] = 'Wikiquote autopatroller protected modules', ['all|portal|all|autopatrol|edit'] = 'Wikiquote autopatroller protected portals', ['all|project|all|autopatrol|edit'] = 'Wikiquote autopatroller protected project pages', ['all|talk|all|autopatrol|edit'] = 'Wikiquote autopatroller protected talk pages', ['all|template|all|autopatrol|edit'] = 'Wikiquote autopatroller protected templates', ['all|user|all|autopatrol|edit'] = 'Wikiquote autopatroller protected user and user talk pages', -- move-protected templates ['all|all|dispute|sysop|edit'] = 'Wikiquote pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikiquote pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikiquote pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikiquote fully protected categories', ['all|file|all|sysop|edit'] = 'Wikiquote fully protected files', ['all|project|all|sysop|edit'] = 'Wikiquote fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikiquote fully protected talk pages', ['all|template|all|sysop|edit'] = 'Wikiquote fully protected templates', ['all|user|all|sysop|edit'] = 'Wikiquote fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikiquote fully protected modules', ['all|all|all|sysop|move'] = 'Wikiquote move-protected pages', ['indef|all|all|sysop|move'] = 'Wikiquote indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikiquote pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikiquote pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikiquote move-protected portals', ['all|project|all|sysop|move'] = 'Wikiquote move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikiquote move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikiquote move-protected templates', ['all|user|all|sysop|move'] = 'Wikiquote move-protected user and user talk pages', ['all|file|all|all|upload'] = 'Wikiquote upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, autopatrol = {'sysop'}, autoconfirmed = {'autopatrolled', 'patroller', 'sysop'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikiquote pages with incorrect protection templates', ['tracking-category-template'] = 'Wikiquote template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } a31bvj6p1e9o2ylmek2n8jf249r37nm 28455 28454 2026-04-10T14:26:59Z en>Codename Noreste 0 Fix. 28455 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[:w:Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[:w:Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently protected from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WQ:NPOV|Neutral Point of View]] and [[WQ:VERIFY|Verifiability]].' .. ' Standard Wikiquote policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, sock = { description = 'For pages protected due to' .. ' [[Wikiquote:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikiquote:Sock puppetry|sock puppets]] of' .. ' [[Wikiquote:Blocking policy|blocked]] or' .. ' [[Wikiquote:Blocking policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For high-risk templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is high-risk.', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if' .. ' it is [[Help:Minor edit|uncontroversial]] or supported by' .. ' consensus. You can also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that the page be unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikiquote:Administrators\' noticeboard|request an edit or unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism#Page move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikiquote:User' .. ' groups#New users|new]] or [[Wikiquote:User groups#Unregistered' .. ' users|unregistered]] users is currently [[Wikiquote:Protection policy|disabled]]', autopatrol = 'This ${PAGETYPE} is currently under autopatroller protection', }, move = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, autopatrol = { default = 'The [[Wikiquote:Protection policy#Autopatroller protection|policy on community use]]' .. ' specifies that autopatroller protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by consensus.' }, default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.' .. ' You may also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that this page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Administrators\' noticeboard' .. ' |request an edit or ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikiquote:Administrators\' noticeboard]].' .. ' You can also [[Wikiquote:Administrators\' noticeboard|' .. ' request]] that the page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. ' protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikiquote:Administrators\' noticeboard]]. You can also' .. ' [[Wikipedia:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', autopatrol = 'Extended-protection-shackle-account-pro-plus.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikiquote:Protection policy#Full protection', autopatrol = 'Wikiquote:Protection policy#Autopatroller protection', autoconfirmed = 'Wikiquote:Protection policy#Semi-protection' }, move = { default = 'Wikiquote:Protection policy#Move protection' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikiquote fully protected pages', ['all|all|office|all|all'] = 'Wikiquote Office-protected pages', ['all|all|reset|all|all'] = 'Wikiquote Office-protected pages', ['all|all|dmca|all|all'] = 'Wikiquote Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikiquote fully protected main page files', ['all|template|all|all|edit'] = 'Wikiquote fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikiquote semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikiquote indefinitely semi-protected pages', ['all|all|dispute|autoconfirmed|edit'] = 'Wikiquote pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikiquote pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikiquote pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikiquote semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikiquote semi-protected files', ['all|module|all|autoconfirmed|edit'] = 'Wikiquote semi-protected modules', ['all|portal|all|autoconfirmed|edit'] = 'Wikiquote semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikiquote semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikiquote semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikiquote semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikiquote semi-protected user and user talk pages', -- move-protected templates ['all|all|all|autopatrol|edit'] = 'Wikiquote autopatroller protected pages', ['all|category|all|autopatrol|edit'] = 'Wikiquote autopatroller protected categories', ['all|file|all|autopatrol|edit'] = 'Wikiquote autopatroller protected files', ['all|module|all|autopatrol|edit'] = 'Wikiquote autopatroller protected modules', ['all|portal|all|autopatrol|edit'] = 'Wikiquote autopatroller protected portals', ['all|project|all|autopatrol|edit'] = 'Wikiquote autopatroller protected project pages', ['all|talk|all|autopatrol|edit'] = 'Wikiquote autopatroller protected talk pages', ['all|template|all|autopatrol|edit'] = 'Wikiquote autopatroller protected templates', ['all|user|all|autopatrol|edit'] = 'Wikiquote autopatroller protected user and user talk pages', -- move-protected templates ['all|all|dispute|sysop|edit'] = 'Wikiquote pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikiquote pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikiquote pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikiquote fully protected categories', ['all|file|all|sysop|edit'] = 'Wikiquote fully protected files', ['all|project|all|sysop|edit'] = 'Wikiquote fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikiquote fully protected talk pages', ['all|template|all|sysop|edit'] = 'Wikiquote fully protected templates', ['all|user|all|sysop|edit'] = 'Wikiquote fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikiquote fully protected modules', ['all|all|all|sysop|move'] = 'Wikiquote move-protected pages', ['indef|all|all|sysop|move'] = 'Wikiquote indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikiquote pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikiquote pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikiquote move-protected portals', ['all|project|all|sysop|move'] = 'Wikiquote move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikiquote move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikiquote move-protected templates', ['all|user|all|sysop|move'] = 'Wikiquote move-protected user and user talk pages', ['all|file|all|all|upload'] = 'Wikiquote upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, autopatrol = {'sysop'}, autoconfirmed = {'autopatrolled', 'patroller', 'sysop'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikiquote pages with incorrect protection templates', ['tracking-category-template'] = 'Wikiquote template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Padlock.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } nksqg4l7tfkxf5nwwpxk0kh658pbezf 28456 28455 2026-04-10T14:34:42Z en>Codename Noreste 0 Another icon change. 28456 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[:w:Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[:w:Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently protected from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WQ:NPOV|Neutral Point of View]] and [[WQ:VERIFY|Verifiability]].' .. ' Standard Wikiquote policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, sock = { description = 'For pages protected due to' .. ' [[Wikiquote:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikiquote:Sock puppetry|sock puppets]] of' .. ' [[Wikiquote:Blocking policy|blocked]] or' .. ' [[Wikiquote:Blocking policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For high-risk templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is high-risk.', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if' .. ' it is [[Help:Minor edit|uncontroversial]] or supported by' .. ' consensus. You can also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that the page be unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikiquote:Administrators\' noticeboard|request an edit or unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism#Page move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikiquote:User' .. ' groups#New users|new]] or [[Wikiquote:User groups#Unregistered' .. ' users|unregistered]] users is currently [[Wikiquote:Protection policy|disabled]]', autopatrol = 'This ${PAGETYPE} is currently under autopatroller protection', }, move = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, autopatrol = { default = 'The [[Wikiquote:Protection policy#Autopatroller protection|policy on community use]]' .. ' specifies that autopatroller protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by consensus.' }, default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.' .. ' You may also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that this page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Administrators\' noticeboard' .. ' |request an edit or ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikiquote:Administrators\' noticeboard]].' .. ' You can also [[Wikiquote:Administrators\' noticeboard|' .. ' request]] that the page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. ' protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikiquote:Administrators\' noticeboard]]. You can also' .. ' [[Wikipedia:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', autopatrol = 'Extended-protection-shackle-account-pro-plus.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikiquote:Protection policy#Full protection', autopatrol = 'Wikiquote:Protection policy#Autopatroller protection', autoconfirmed = 'Wikiquote:Protection policy#Semi-protection' }, move = { default = 'Wikiquote:Protection policy#Move protection' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikiquote fully protected pages', ['all|all|office|all|all'] = 'Wikiquote Office-protected pages', ['all|all|reset|all|all'] = 'Wikiquote Office-protected pages', ['all|all|dmca|all|all'] = 'Wikiquote Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikiquote fully protected main page files', ['all|template|all|all|edit'] = 'Wikiquote fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikiquote semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikiquote indefinitely semi-protected pages', ['all|all|dispute|autoconfirmed|edit'] = 'Wikiquote pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikiquote pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikiquote pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikiquote semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikiquote semi-protected files', ['all|module|all|autoconfirmed|edit'] = 'Wikiquote semi-protected modules', ['all|portal|all|autoconfirmed|edit'] = 'Wikiquote semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikiquote semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikiquote semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikiquote semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikiquote semi-protected user and user talk pages', -- move-protected templates ['all|all|all|autopatrol|edit'] = 'Wikiquote autopatroller protected pages', ['all|category|all|autopatrol|edit'] = 'Wikiquote autopatroller protected categories', ['all|file|all|autopatrol|edit'] = 'Wikiquote autopatroller protected files', ['all|module|all|autopatrol|edit'] = 'Wikiquote autopatroller protected modules', ['all|portal|all|autopatrol|edit'] = 'Wikiquote autopatroller protected portals', ['all|project|all|autopatrol|edit'] = 'Wikiquote autopatroller protected project pages', ['all|talk|all|autopatrol|edit'] = 'Wikiquote autopatroller protected talk pages', ['all|template|all|autopatrol|edit'] = 'Wikiquote autopatroller protected templates', ['all|user|all|autopatrol|edit'] = 'Wikiquote autopatroller protected user and user talk pages', -- move-protected templates ['all|all|dispute|sysop|edit'] = 'Wikiquote pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikiquote pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikiquote pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikiquote fully protected categories', ['all|file|all|sysop|edit'] = 'Wikiquote fully protected files', ['all|project|all|sysop|edit'] = 'Wikiquote fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikiquote fully protected talk pages', ['all|template|all|sysop|edit'] = 'Wikiquote fully protected templates', ['all|user|all|sysop|edit'] = 'Wikiquote fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikiquote fully protected modules', ['all|all|all|sysop|move'] = 'Wikiquote move-protected pages', ['indef|all|all|sysop|move'] = 'Wikiquote indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikiquote pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikiquote pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikiquote move-protected portals', ['all|project|all|sysop|move'] = 'Wikiquote move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikiquote move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikiquote move-protected templates', ['all|user|all|sysop|move'] = 'Wikiquote move-protected user and user talk pages', ['all|file|all|all|upload'] = 'Wikiquote upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, autopatrol = {'sysop'}, autoconfirmed = {'autopatrolled', 'patroller', 'sysop'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikiquote pages with incorrect protection templates', ['tracking-category-template'] = 'Wikiquote template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } ff0d2u4lcplpz7xxoocrlgqctwno5bt 28457 28456 2026-10-24T01:16:14Z Kiran Gopi 624 [[:en:Module:Protection_banner/config]] എന്നതിൽ നിന്ന് 155 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28456 Scribunto text/plain -- This module provides configuration data for [[Module:Protection banner]]. return { -------------------------------------------------------------------------------- -- -- BANNER DATA -- -------------------------------------------------------------------------------- --[[ -- Banner data consists of six fields: -- * text - the main protection text that appears at the top of protection -- banners. -- * explanation - the text that appears below the main protection text, used -- to explain the details of the protection. -- * tooltip - the tooltip text you see when you move the mouse over a small -- padlock icon. -- * link - the page that the small padlock icon links to. -- * alt - the alt text for the small padlock icon. This is also used as tooltip -- text for the large protection banners. -- * image - the padlock image used in both protection banners and small padlock -- icons. -- -- The module checks in three separate tables to find a value for each field. -- First it checks the banners table, which has values specific to the reason -- for the page being protected. Then the module checks the defaultBanners -- table, which has values specific to each protection level. Finally, the -- module checks the masterBanner table, which holds data for protection -- templates to use if no data has been found in the previous two tables. -- -- The values in the banner data can take parameters. These are specified -- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name -- enclosed in curly braces). -- -- Available parameters: -- -- ${CURRENTVERSION} - a link to the page history or the move log, with the -- display message "current-version-edit-display" or -- "current-version-move-display". -- -- ${EDITREQUEST} - a link to create an edit request for the current page. -- -- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes -- on the talk page; you may submit a request to ask an administrator to make -- an edit if it is minor or supported by consensus." -- -- ${IMAGELINK} - a link to set the image to, depending on the protection -- action and protection level. -- -- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry -- is set. E.g. "Editing of this page by new or unregistered users is currently -- disabled until dd Month YYYY." -- -- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation -- so that it can be used in run-on sentences. -- -- ${PAGETYPE} - the type of the page, e.g. "article" or "template". -- Defined in the cfg.pagetypes table. -- -- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g. -- "Editing of this page by new or unregistered users is currently disabled" -- -- ${PROTECTIONDATE} - the protection date, if it has been supplied to the -- template. -- -- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or -- "semi-protected". -- -- ${PROTECTIONLOG} - a link to the protection log or the pending changes log, -- depending on the protection action. -- -- ${TALKPAGE} - a link to the talk page. If a section is specified, links -- straight to that talk page section. -- -- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to -- create a blurb like "This template is semi-protected", or "This article is -- move-protected until DD Month YYYY". -- -- ${VANDAL} - links for the specified username (or the root page name) -- using Module:Vandal-m. -- -- Functions -- -- For advanced users, it is possible to use Lua functions instead of strings -- in the banner config tables. Using functions gives flexibility that is not -- possible just by using parameters. Functions take two arguments, the -- protection object and the template arguments, and they must output a string. -- -- For example: -- -- text = function (protectionObj, args) -- if protectionObj.level == 'autoconfirmed' then -- return 'foo' -- else -- return 'bar' -- end -- end -- -- Some protection object properties and methods that may be useful: -- protectionObj.action - the protection action -- protectionObj.level - the protection level -- protectionObj.reason - the protection reason -- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set -- to indefinite, and the protection time in unix time if temporary. -- protectionObj.protectionDate - the protection date in unix time, or nil if -- unspecified. -- protectionObj.bannerConfig - the banner config found by the module. Beware -- of editing the config field used by the function, as it could create an -- infinite loop. -- protectionObj:isProtected - returns a boolean showing whether the page is -- protected. -- protectionObj:isTemporary - returns a boolean showing whether the expiry is -- temporary. -- protectionObj:isIncorrect - returns a boolean showing whether the protection -- template is incorrect. --]] -- The master banner data, used if no values have been found in banners or -- defaultBanners. masterBanner = { text = '${INTROBLURB}', explanation = '${EXPLANATIONBLURB}', tooltip = '${TOOLTIPBLURB}', link = '${IMAGELINK}', alt = 'Page ${PROTECTIONLEVEL}' }, -- The default banner data. This holds banner data for different protection -- levels. -- *required* - this table needs edit, move, autoreview and upload subtables. defaultBanners = { edit = {}, move = {}, autoreview = { default = { alt = 'Page protected with pending changes', tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users', image = 'Pending-protection-shackle.svg' } }, upload = {} }, -- The banner data. This holds banner data for different protection reasons. -- In fact, the reasons specified in this table control which reasons are -- valid inputs to the first positional parameter. -- -- There is also a non-standard "description" field that can be used for items -- in this table. This is a description of the protection reason for use in the -- module documentation. -- -- *required* - this table needs edit, move, autoreview and upload subtables. banners = { edit = { dmca = { description = 'For pages protected by the Wikimedia Foundation' .. ' due to Digital Millennium Copyright Act takedown requests', explanation = function (protectionObj, args) local ret = 'Pursuant to a rights owner notice under the Digital' .. ' Millennium Copyright Act (DMCA) regarding some content' .. ' in this article, the Wikimedia Foundation acted under' .. ' applicable law and took down and restricted the content' .. ' in question.' if args.notice then ret = ret .. ' A copy of the received notice can be found here: ' .. args.notice .. '.' end ret = ret .. ' For more information, including websites discussing' .. ' how to file a counter-notice, please see' .. " [[:w:Wikipedia:Office actions]] and the article's ${TALKPAGE}." .. "'''Do not remove this template from the article until the" .. " restrictions are withdrawn'''." return ret end, image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, dispute = { description = 'For pages protected due to editing disputes', text = function (protectionObj, args) -- Find the value of "disputes". local display = 'disputes' local disputes if args.section then disputes = string.format( '[[%s:%s#%s|%s]]', mw.site.namespaces[protectionObj.title.namespace].talk.name, protectionObj.title.text, args.section, display ) else disputes = display end -- Make the blurb, depending on the expiry. local msg if type(protectionObj.expiry) == 'number' then msg = '${INTROFRAGMENT} or until editing %s have been resolved.' else msg = '${INTROFRAGMENT} until editing %s have been resolved.' end return string.format(msg, disputes) end, explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', tooltip = '${TOOLTIPFRAGMENT} due to editing disputes', }, ecp = { description = 'For articles in topic areas authorized by' .. ' [[:w:Wikipedia:Arbitration Committee|ArbCom]] or' .. ' meets the criteria for community use', tooltip = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', alt = 'Extended-protected ${PAGETYPE}', }, mainpage = { description = 'For pages protected for being displayed on the [[Main Page]]', text = 'This file is currently protected from' .. ' editing because it is currently or will soon be displayed' .. ' on the [[Main Page]].', explanation = 'Images on the Main Page are protected due to their high' .. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.' .. '<br /><span style="font-size:90%;">' .. "'''Administrators:''' Once this image is definitely off the Main Page," .. ' please unprotect this file, or reduce to semi-protection,' .. ' as appropriate.</span>', }, office = { description = 'For pages protected by the Wikimedia Foundation', text = function (protectionObj, args) local ret = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.' if protectionObj.protectionDate then ret = ret .. ' It has been protected since ${PROTECTIONDATE}.' end return ret end, explanation = "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not remove protection from this" .. " page unless you are authorized by the Wikimedia Foundation to do" .. " so.'''", image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, reset = { description = 'For pages protected by the Wikimedia Foundation and' .. ' "reset" to a bare-bones version', text = 'This ${PAGETYPE} is currently under the' .. ' scrutiny of the' .. ' [[:w:Wikipedia:Office actions|Wikimedia Foundation Office]]' .. ' and is protected.', explanation = function (protectionObj, args) local ret = '' if protectionObj.protectionDate then ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was' else ret = ret .. 'This ${PAGETYPE} has been' end ret = ret .. ' reduced to a' .. ' simplified, "bare bones" version so that it may be completely' .. ' rewritten to ensure it meets the policies of' .. ' [[WQ:NPOV|Neutral Point of View]] and [[WQ:VERIFY|Verifiability]].' .. ' Standard Wikiquote policies will apply to its rewriting—which' .. ' will eventually be open to all editors—and will be strictly' .. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while' .. ' it is being rebuilt.\n\n' .. 'Any insertion of material directly from' .. ' pre-protection revisions of the ${PAGETYPE} will be removed, as' .. ' will any material added to the ${PAGETYPE} that is not properly' .. ' sourced. The associated talk page(s) were also cleared on the' .. " same date.\n\n" .. "If you can edit this page, please discuss all changes and" .. " additions on the ${TALKPAGE} first. '''Do not override" .. " this action, and do not remove protection from this page," .. " unless you are authorized by the Wikimedia Foundation" .. " to do so. No editor may remove this notice.'''" return ret end, image = 'Office-protection-shackle.svg', link = 'Wikiquote:Protection policy#Office actions', }, sock = { description = 'For pages protected due to' .. ' [[Wikiquote:Sock puppetry|sock puppetry]]', text = '${INTROFRAGMENT} to prevent [[Wikiquote:Sock puppetry|sock puppets]] of' .. ' [[Wikiquote:Blocking policy|blocked]] or' .. ' [[Wikiquote:Blocking policy|banned users]]' .. ' from editing it.', tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from' .. ' editing it', }, template = { description = 'For high-risk templates and Lua modules', text = 'This is a permanently [[Help:Protection|protected]] ${PAGETYPE},' .. ' as it is high-risk.', explanation = 'Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if' .. ' it is [[Help:Minor edit|uncontroversial]] or supported by' .. ' consensus. You can also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that the page be unprotected.', tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}' .. ' to prevent vandalism', alt = 'Permanently protected ${PAGETYPE}', }, usertalk = { description = 'For pages protected against disruptive edits by a' .. ' particular user', text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,' .. ' such as abusing the' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; template.', explanation = 'If you cannot edit this user talk page and you need to' .. ' make a change or leave a message, you can' .. ' [[Wikiquote:Administrators\' noticeboard|request an edit or unprotection]],' .. ' [[Special:Userlogin|log in]],' .. ' or [[Special:UserLogin/signup|create an account]].', }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism|vandalism]]', text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].', explanation = function (protectionObj, args) local ret = '' if protectionObj.level == 'sysop' then ret = ret .. "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ' end return ret .. '${EXPLANATIONBLURB}' end, tooltip = '${TOOLTIPFRAGMENT} due to vandalism', } }, move = { dispute = { description = 'For pages protected against page moves due to' .. ' disputes over the page title', explanation = "This protection is '''not''' an endorsement of the" .. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}', image = 'Move-protection-shackle.svg' }, vandalism = { description = 'For pages protected against' .. ' [[Wikiquote:Vandalism#Page move vandalism' .. ' |page-move vandalism]]' } }, autoreview = {}, upload = {} }, -------------------------------------------------------------------------------- -- -- GENERAL DATA TABLES -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Protection blurbs -------------------------------------------------------------------------------- -- This table produces the protection blurbs available with the -- ${PROTECTIONBLURB} parameter. It is sorted by protection action and -- protection level, and is checked by the module in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionBlurbs = { edit = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|' .. 'protected]] from editing', autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikiquote:User' .. ' groups#New users|new]] or [[Wikiquote:User groups#Unregistered' .. ' users|unregistered]] users is currently [[Wikiquote:Protection policy|disabled]]', autopatrol = 'This ${PAGETYPE} is currently under autopatroller protection', }, move = { default = 'This ${PAGETYPE} is currently [[Wikiquote:Protection policy|protected]]' .. ' from [[Help:Moving a page|page moves]]' }, upload = { default = 'Uploading new versions of this ${PAGETYPE} is currently disabled' } }, -------------------------------------------------------------------------------- -- Explanation blurbs -------------------------------------------------------------------------------- -- This table produces the explanation blurbs available with the -- ${EXPLANATIONBLURB} parameter. It is sorted by protection action, -- protection level, and whether the page is a talk page or not. If the page is -- a talk page it will have a talk key of "talk"; otherwise it will have a talk -- key of "subject". The table is checked in the following order: -- 1. page's protection action, page's protection level, page's talk key -- 2. page's protection action, page's protection level, default talk key -- 3. page's protection action, default protection level, page's talk key -- 4. page's protection action, default protection level, default talk key -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. explanationBlurbs = { edit = { autoconfirmed = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details. If you' .. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can' .. ' [[Wikipedia:Administrators\' noticeboard|request' .. ' unprotection]], [[Special:Userlogin|log in]], or' .. ' [[Special:UserLogin/signup|create an account]].', }, autopatrol = { default = 'The [[Wikiquote:Protection policy#Autopatroller protection|policy on community use]]' .. ' specifies that autopatroller protection can be applied to combat' .. ' disruption, if semi-protection has proven to be ineffective.' .. ' Please discuss any changes on the ${TALKPAGE}; you may' .. ' ${EDITREQUEST} to ask for uncontroversial changes supported by consensus.' }, default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.' .. ' You may also [[Wikiquote:Administrators\' noticeboard|request]]' .. ' that this page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' You may [[Wikipedia:Administrators\' noticeboard' .. ' |request an edit or ask]] for it to be unprotected.' } }, move = { default = { subject = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves on the' .. ' ${TALKPAGE} or at [[Wikiquote:Administrators\' noticeboard]].' .. ' You can also [[Wikiquote:Administrators\' noticeboard|' .. ' request]] that the page be unprotected.', default = 'See the [[Wikiquote:Protection policy|' .. ' protection policy]] and ${PROTECTIONLOG} for more details.' .. ' The page may still be edited but cannot be moved' .. ' until unprotected. Please discuss any suggested moves at' .. ' [[Wikiquote:Administrators\' noticeboard]]. You can also' .. ' [[Wikipedia:Administrators\' noticeboard|request]] that the page be' .. ' unprotected.' } } }, -------------------------------------------------------------------------------- -- Protection levels -------------------------------------------------------------------------------- -- This table provides the data for the ${PROTECTIONLEVEL} parameter, which -- produces a short label for different protection levels. It is sorted by -- protection action and protection level, and is checked in the following -- order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. protectionLevels = { edit = { default = 'protected', autoconfirmed = 'semi-protected', }, move = { default = 'move-protected' } }, -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- This table lists different padlock images for each protection action and -- protection level. It is used if an image is not specified in any of the -- banner data tables, and if the page does not satisfy the conditions for using -- the ['image-filename-indef'] image. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level images = { edit = { default = 'Full-protection-shackle.svg', autopatrol = 'Extended-protection-shackle-account-pro-plus.svg', autoconfirmed = 'Semi-protection-shackle.svg' }, move = { default = 'Move-protection-shackle.svg', } }, -- Pages with a reason specified in this table will show the special "indef" -- padlock, defined in the 'image-filename-indef' message, if no expiry is set. indefImageReasons = { template = true }, -------------------------------------------------------------------------------- -- Image links -------------------------------------------------------------------------------- -- This table provides the data for the ${IMAGELINK} parameter, which gets -- the image link for small padlock icons based on the page's protection action -- and protection level. It is checked in the following order: -- 1. page's protection action, page's protection level -- 2. page's protection action, default protection level -- 3. "edit" protection action, default protection level -- -- It is possible to use banner parameters inside this table. -- *required* - this table needs edit, move, autoreview and upload subtables. imageLinks = { edit = { default = 'Wikiquote:Protection policy#Full protection', autopatrol = 'Wikiquote:Protection policy#Autopatroller protection', autoconfirmed = 'Wikiquote:Protection policy#Semi-protection' }, move = { default = 'Wikiquote:Protection policy#Move protection' } }, -------------------------------------------------------------------------------- -- Padlock indicator names -------------------------------------------------------------------------------- -- This table provides the "name" attribute for the <indicator> extension tag -- with which small padlock icons are generated. All indicator tags on a page -- are displayed in alphabetical order based on this attribute, and with -- indicator tags with duplicate names, the last tag on the page wins. -- The attribute is chosen based on the protection action; table keys must be a -- protection action name or the string "default". padlockIndicatorNames = { autoreview = 'pp-autoreview', default = 'pp-default' }, -------------------------------------------------------------------------------- -- Protection categories -------------------------------------------------------------------------------- --[[ -- The protection categories are stored in the protectionCategories table. -- Keys to this table are made up of the following strings: -- -- 1. the expiry date -- 2. the namespace -- 3. the protection reason (e.g. "dispute" or "vandalism") -- 4. the protection level (e.g. "sysop" or "autoconfirmed") -- 5. the action (e.g. "edit" or "move") -- -- When the module looks up a category in the table, first it will will check to -- see a key exists that corresponds to all five parameters. For example, a -- user page semi-protected from vandalism for two weeks would have the key -- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module -- changes the first part of the key to "all" and checks the table again. It -- keeps checking increasingly generic key combinations until it finds the -- field, or until it reaches the key "all-all-all-all-all". -- -- The module uses a binary matrix to determine the order in which to search. -- This is best demonstrated by a table. In this table, the "0" values -- represent "all", and the "1" values represent the original data (e.g. -- "indef" or "file" or "vandalism"). -- -- expiry namespace reason level action -- order -- 1 1 1 1 1 1 -- 2 0 1 1 1 1 -- 3 1 0 1 1 1 -- 4 0 0 1 1 1 -- 5 1 1 0 1 1 -- 6 0 1 0 1 1 -- 7 1 0 0 1 1 -- 8 0 0 0 1 1 -- 9 1 1 1 0 1 -- 10 0 1 1 0 1 -- 11 1 0 1 0 1 -- 12 0 0 1 0 1 -- 13 1 1 0 0 1 -- 14 0 1 0 0 1 -- 15 1 0 0 0 1 -- 16 0 0 0 0 1 -- 17 1 1 1 1 0 -- 18 0 1 1 1 0 -- 19 1 0 1 1 0 -- 20 0 0 1 1 0 -- 21 1 1 0 1 0 -- 22 0 1 0 1 0 -- 23 1 0 0 1 0 -- 24 0 0 0 1 0 -- 25 1 1 1 0 0 -- 26 0 1 1 0 0 -- 27 1 0 1 0 0 -- 28 0 0 1 0 0 -- 29 1 1 0 0 0 -- 30 0 1 0 0 0 -- 31 1 0 0 0 0 -- 32 0 0 0 0 0 -- -- In this scheme the action has the highest priority, as it is the last -- to change, and the expiry has the least priority, as it changes the most. -- The priorities of the expiry, the protection level and the action are -- fixed, but the priorities of the reason and the namespace can be swapped -- through the use of the cfg.bannerDataNamespaceHasPriority table. --]] -- If the reason specified to the template is listed in this table, -- namespace data will take priority over reason data in the protectionCategories -- table. reasonsWithNamespacePriority = { vandalism = true, }, -- The string to use as a namespace key for the protectionCategories table for each -- namespace number. categoryNamespaceKeys = { [ 2] = 'user', [ 3] = 'user', [ 4] = 'project', [ 6] = 'file', [ 8] = 'mediawiki', [ 10] = 'template', [ 12] = 'project', [ 14] = 'category', [100] = 'portal', [828] = 'module', }, protectionCategories = { ['all|all|all|all|all'] = 'Wikiquote fully protected pages', ['all|all|office|all|all'] = 'Wikiquote Office-protected pages', ['all|all|reset|all|all'] = 'Wikiquote Office-protected pages', ['all|all|dmca|all|all'] = 'Wikiquote Office-protected pages', ['all|all|mainpage|all|all'] = 'Wikiquote fully protected main page files', ['all|template|all|all|edit'] = 'Wikiquote fully protected templates', ['all|all|all|autoconfirmed|edit'] = 'Wikiquote semi-protected pages', ['indef|all|all|autoconfirmed|edit'] = 'Wikiquote indefinitely semi-protected pages', ['all|all|dispute|autoconfirmed|edit'] = 'Wikiquote pages semi-protected due to dispute', ['all|all|sock|autoconfirmed|edit'] = 'Wikiquote pages semi-protected from banned users', ['all|all|vandalism|autoconfirmed|edit'] = 'Wikiquote pages semi-protected against vandalism', ['all|category|all|autoconfirmed|edit'] = 'Wikiquote semi-protected categories', ['all|file|all|autoconfirmed|edit'] = 'Wikiquote semi-protected files', ['all|module|all|autoconfirmed|edit'] = 'Wikiquote semi-protected modules', ['all|portal|all|autoconfirmed|edit'] = 'Wikiquote semi-protected portals', ['all|project|all|autoconfirmed|edit'] = 'Wikiquote semi-protected project pages', ['all|talk|all|autoconfirmed|edit'] = 'Wikiquote semi-protected talk pages', ['all|template|all|autoconfirmed|edit'] = 'Wikiquote semi-protected templates', ['all|user|all|autoconfirmed|edit'] = 'Wikiquote semi-protected user and user talk pages', -- move-protected templates ['all|all|all|autopatrol|edit'] = 'Wikiquote autopatroller protected pages', ['all|category|all|autopatrol|edit'] = 'Wikiquote autopatroller protected categories', ['all|file|all|autopatrol|edit'] = 'Wikiquote autopatroller protected files', ['all|module|all|autopatrol|edit'] = 'Wikiquote autopatroller protected modules', ['all|portal|all|autopatrol|edit'] = 'Wikiquote autopatroller protected portals', ['all|project|all|autopatrol|edit'] = 'Wikiquote autopatroller protected project pages', ['all|talk|all|autopatrol|edit'] = 'Wikiquote autopatroller protected talk pages', ['all|template|all|autopatrol|edit'] = 'Wikiquote autopatroller protected templates', ['all|user|all|autopatrol|edit'] = 'Wikiquote autopatroller protected user and user talk pages', -- move-protected templates ['all|all|dispute|sysop|edit'] = 'Wikiquote pages protected due to dispute', ['all|all|sock|sysop|edit'] = 'Wikiquote pages protected from banned users', ['all|all|vandalism|sysop|edit'] = 'Wikiquote pages protected against vandalism', ['all|category|all|sysop|edit'] = 'Wikiquote fully protected categories', ['all|file|all|sysop|edit'] = 'Wikiquote fully protected files', ['all|project|all|sysop|edit'] = 'Wikiquote fully protected project pages', ['all|talk|all|sysop|edit'] = 'Wikiquote fully protected talk pages', ['all|template|all|sysop|edit'] = 'Wikiquote fully protected templates', ['all|user|all|sysop|edit'] = 'Wikiquote fully protected user and user talk pages', ['all|module|all|all|edit'] = 'Wikiquote fully protected modules', ['all|all|all|sysop|move'] = 'Wikiquote move-protected pages', ['indef|all|all|sysop|move'] = 'Wikiquote indefinitely move-protected pages', ['all|all|dispute|sysop|move'] = 'Wikiquote pages move-protected due to dispute', ['all|all|vandalism|sysop|move'] = 'Wikiquote pages move-protected due to vandalism', ['all|portal|all|sysop|move'] = 'Wikiquote move-protected portals', ['all|project|all|sysop|move'] = 'Wikiquote move-protected project pages', ['all|talk|all|sysop|move'] = 'Wikiquote move-protected talk pages', ['all|template|all|sysop|move'] = 'Wikiquote move-protected templates', ['all|user|all|sysop|move'] = 'Wikiquote move-protected user and user talk pages', ['all|file|all|all|upload'] = 'Wikiquote upload-protected files', }, -------------------------------------------------------------------------------- -- Expiry category config -------------------------------------------------------------------------------- -- This table configures the expiry category behaviour for each protection -- action. -- * If set to true, setting that action will always categorise the page if -- an expiry parameter is not set. -- * If set to false, setting that action will never categorise the page. -- * If set to nil, the module will categorise the page if: -- 1) an expiry parameter is not set, and -- 2) a reason is provided, and -- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck -- table. expiryCheckActions = { edit = nil, move = false, autoreview = true, upload = false }, reasonsWithoutExpiryCheck = { blp = true, template = true, }, -------------------------------------------------------------------------------- -- Pagetypes -------------------------------------------------------------------------------- -- This table produces the page types available with the ${PAGETYPE} parameter. -- Keys are namespace numbers, or the string "default" for the default value. pagetypes = { [0] = 'article', [6] = 'file', [10] = 'template', [14] = 'category', [828] = 'module', default = 'page' }, -------------------------------------------------------------------------------- -- Strings marking indefinite protection -------------------------------------------------------------------------------- -- This table contains values passed to the expiry parameter that mean the page -- is protected indefinitely. indefStrings = { ['indef'] = true, ['indefinite'] = true, ['indefinitely'] = true, ['infinite'] = true, }, -------------------------------------------------------------------------------- -- Group hierarchy -------------------------------------------------------------------------------- -- This table maps each group to all groups that have a superset of the original -- group's page editing permissions. hierarchy = { sysop = {}, autopatrol = {'sysop'}, autoconfirmed = {'autopatrolled', 'patroller', 'sysop'}, user = {'autoconfirmed'}, ['*'] = {'user'} }, -------------------------------------------------------------------------------- -- Wrapper templates and their default arguments -------------------------------------------------------------------------------- -- This table contains wrapper templates used with the module, and their -- default arguments. Templates specified in this table should contain the -- following invocation, and no other template content: -- -- {{#invoke:Protection banner|main}} -- -- If other content is desired, it can be added between -- <noinclude>...</noinclude> tags. -- -- When a user calls one of these wrapper templates, they will use the -- default arguments automatically. However, users can override any of the -- arguments. wrappers = { ['Template:Pp'] = {}, ['Template:Protection padlock'] = {}, ['Template:Pp-extended'] = {'ecp'}, ['Template:Pp-blp'] = {'blp'}, -- we don't need Template:Pp-create ['Template:Pp-dispute'] = {'dispute'}, ['Template:Pp-main-page'] = {'mainpage'}, ['Template:Pp-move'] = {action = 'move', catonly = 'yes'}, ['Template:Pp-move-dispute'] = {'dispute', action = 'move', catonly = 'yes'}, -- we don't need Template:Pp-move-indef ['Template:Pp-move-vandalism'] = {'vandalism', action = 'move', catonly = 'yes'}, ['Template:Pp-office'] = {'office'}, ['Template:Pp-office-dmca'] = {'dmca'}, ['Template:Pp-pc'] = {action = 'autoreview', small = true}, ['Template:Pp-pc1'] = {action = 'autoreview', small = true}, ['Template:Pp-reset'] = {'reset'}, ['Template:Pp-semi-indef'] = {small = true}, ['Template:Pp-sock'] = {'sock'}, ['Template:Pp-template'] = {'template', small = true}, ['Template:Pp-upload'] = {action = 'upload'}, ['Template:Pp-usertalk'] = {'usertalk'}, ['Template:Pp-vandalism'] = {'vandalism'}, }, -------------------------------------------------------------------------------- -- -- MESSAGES -- -------------------------------------------------------------------------------- msg = { -------------------------------------------------------------------------------- -- Intro blurb and intro fragment -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${INTROBLURB} and -- ${INTROFRAGMENT} parameters. If the protection is temporary they use the -- intro-blurb-expiry or intro-fragment-expiry, and if not they use -- intro-blurb-noexpiry or intro-fragment-noexpiry. -- It is possible to use banner parameters in these messages. ['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.', ['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.', ['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},', ['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}', -------------------------------------------------------------------------------- -- Tooltip blurb -------------------------------------------------------------------------------- -- These messages specify what is produced by the ${TOOLTIPBLURB} parameter. -- If the protection is temporary the tooltip-blurb-expiry message is used, and -- if not the tooltip-blurb-noexpiry message is used. -- It is possible to use banner parameters in these messages. ['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.', ['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.', ['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},', ['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}', -------------------------------------------------------------------------------- -- Special explanation blurb -------------------------------------------------------------------------------- -- An explanation blurb for pages that cannot be unprotected, e.g. for pages -- in the MediaWiki namespace. -- It is possible to use banner parameters in this message. ['explanation-blurb-nounprotect'] = 'See the [[Wikiquote:Protection policy|' .. 'protection policy]] and ${PROTECTIONLOG} for more details.' .. ' Please discuss any changes on the ${TALKPAGE}; you' .. ' may ${EDITREQUEST} to ask an' .. ' [[Wikiquote:Administrators|administrator]] to make an edit if it' .. ' is [[Help:Minor edit|uncontroversial]] or supported by consensus.', -------------------------------------------------------------------------------- -- Protection log display values -------------------------------------------------------------------------------- -- These messages determine the display values for the protection log link -- or the pending changes log link produced by the ${PROTECTIONLOG} parameter. -- It is possible to use banner parameters in these messages. ['protection-log-display'] = 'protection log', ['pc-log-display'] = 'pending changes log', -------------------------------------------------------------------------------- -- Current version display values -------------------------------------------------------------------------------- -- These messages determine the display values for the page history link -- or the move log link produced by the ${CURRENTVERSION} parameter. -- It is possible to use banner parameters in these messages. ['current-version-move-display'] = 'current title', ['current-version-edit-display'] = 'current version', -------------------------------------------------------------------------------- -- Talk page -------------------------------------------------------------------------------- -- This message determines the display value of the talk page link produced -- with the ${TALKPAGE} parameter. -- It is possible to use banner parameters in this message. ['talk-page-link-display'] = 'talk page', -------------------------------------------------------------------------------- -- Edit requests -------------------------------------------------------------------------------- -- This message determines the display value of the edit request link produced -- with the ${EDITREQUEST} parameter. -- It is possible to use banner parameters in this message. ['edit-request-display'] = 'submit an edit request', -------------------------------------------------------------------------------- -- Expiry date format -------------------------------------------------------------------------------- -- This is the format for the blurb expiry date. It should be valid input for -- the first parameter of the #time parser function. ['expiry-date-format'] = 'F j, Y "at" H:i e', -------------------------------------------------------------------------------- -- Tracking categories -------------------------------------------------------------------------------- -- These messages determine which tracking categories the module outputs. ['tracking-category-incorrect'] = 'Wikiquote pages with incorrect protection templates', ['tracking-category-template'] = 'Wikiquote template-protected pages other than templates and modules', -------------------------------------------------------------------------------- -- Images -------------------------------------------------------------------------------- -- These are images that are not defined by their protection action and protection level. ['image-filename-indef'] = 'Full-protection-shackle.svg', ['image-filename-default'] = 'Transparent.gif', -------------------------------------------------------------------------------- -- End messages -------------------------------------------------------------------------------- } -------------------------------------------------------------------------------- -- End configuration -------------------------------------------------------------------------------- } ff0d2u4lcplpz7xxoocrlgqctwno5bt ഘടകം:File link 828 7376 28458 2022-06-14T19:01:18Z en>Ilovemydoodle 0 Created page with "-- This module provides a library for formatting file wikilinks. local yesno = require('Module:Yesno') local checkType = require('libraryUtil').checkType local p = {} function p._main(args) checkType('_main', 1, args, 'table') -- This is basically libraryUtil.checkTypeForNamedArg, but we are rolling our -- own function to get the right error level. local function checkArg(key, val, level) if type(val) ~= 'string' then error(string.format( "type error in..." 28458 Scribunto text/plain -- This module provides a library for formatting file wikilinks. local yesno = require('Module:Yesno') local checkType = require('libraryUtil').checkType local p = {} function p._main(args) checkType('_main', 1, args, 'table') -- This is basically libraryUtil.checkTypeForNamedArg, but we are rolling our -- own function to get the right error level. local function checkArg(key, val, level) if type(val) ~= 'string' then error(string.format( "type error in '%s' parameter of '_main' (expected string, got %s)", key, type(val) ), level) end end local ret = {} -- Adds a positional parameter to the buffer. local function addPositional(key) local val = args[key] if not val then return nil end checkArg(key, val, 4) ret[#ret + 1] = val end -- Adds a named parameter to the buffer. We assume that the parameter name -- is the same as the argument key. local function addNamed(key) local val = args[key] if not val then return nil end checkArg(key, val, 4) ret[#ret + 1] = key .. '=' .. val end -- Filename checkArg('file', args.file, 3) ret[#ret + 1] = 'File:' .. args.file -- Format if args.format then checkArg('format', args.format) if args.formatfile then checkArg('formatfile', args.formatfile) ret[#ret + 1] = args.format .. '=' .. args.formatfile else ret[#ret + 1] = args.format end end -- Border if yesno(args.border) then ret[#ret + 1] = 'border' end addPositional('location') addPositional('alignment') addPositional('size') addNamed('upright') addNamed('link') addNamed('alt') addNamed('page') addNamed('class') addNamed('lang') addNamed('start') addNamed('end') addNamed('thumbtime') addPositional('caption') return string.format('[[%s]]', table.concat(ret, '|')) end function p.main(frame) local origArgs = require('Module:Arguments').getArgs(frame, { wrappers = 'Template:File link' }) if not origArgs.file then error("'file' parameter missing from [[Template:File link]]", 0) end -- Copy the arguments that were passed to a new table to avoid looking up -- every possible parameter in the frame object. local args = {} for k, v in pairs(origArgs) do -- Make _BLANK a special argument to add a blank parameter. For use in -- conditional templates etc. it is useful for blank arguments to be -- ignored, but we still need a way to specify them so that we can do -- things like [[File:Example.png|link=]]. if v == '_BLANK' then v = '' end args[k] = v end return p._main(args) end return p bzc22v133v9z5yc4aisazripn6l94p8 28459 28458 2026-10-24T01:16:14Z Kiran Gopi 624 [[:en:Module:File_link]] എന്നതിൽ നിന്ന് ഒരു പതിപ്പ് ഇറക്കുമതി ചെയ്തു 28458 Scribunto text/plain -- This module provides a library for formatting file wikilinks. local yesno = require('Module:Yesno') local checkType = require('libraryUtil').checkType local p = {} function p._main(args) checkType('_main', 1, args, 'table') -- This is basically libraryUtil.checkTypeForNamedArg, but we are rolling our -- own function to get the right error level. local function checkArg(key, val, level) if type(val) ~= 'string' then error(string.format( "type error in '%s' parameter of '_main' (expected string, got %s)", key, type(val) ), level) end end local ret = {} -- Adds a positional parameter to the buffer. local function addPositional(key) local val = args[key] if not val then return nil end checkArg(key, val, 4) ret[#ret + 1] = val end -- Adds a named parameter to the buffer. We assume that the parameter name -- is the same as the argument key. local function addNamed(key) local val = args[key] if not val then return nil end checkArg(key, val, 4) ret[#ret + 1] = key .. '=' .. val end -- Filename checkArg('file', args.file, 3) ret[#ret + 1] = 'File:' .. args.file -- Format if args.format then checkArg('format', args.format) if args.formatfile then checkArg('formatfile', args.formatfile) ret[#ret + 1] = args.format .. '=' .. args.formatfile else ret[#ret + 1] = args.format end end -- Border if yesno(args.border) then ret[#ret + 1] = 'border' end addPositional('location') addPositional('alignment') addPositional('size') addNamed('upright') addNamed('link') addNamed('alt') addNamed('page') addNamed('class') addNamed('lang') addNamed('start') addNamed('end') addNamed('thumbtime') addPositional('caption') return string.format('[[%s]]', table.concat(ret, '|')) end function p.main(frame) local origArgs = require('Module:Arguments').getArgs(frame, { wrappers = 'Template:File link' }) if not origArgs.file then error("'file' parameter missing from [[Template:File link]]", 0) end -- Copy the arguments that were passed to a new table to avoid looking up -- every possible parameter in the frame object. local args = {} for k, v in pairs(origArgs) do -- Make _BLANK a special argument to add a blank parameter. For use in -- conditional templates etc. it is useful for blank arguments to be -- ignored, but we still need a way to specify them so that we can do -- things like [[File:Example.png|link=]]. if v == '_BLANK' then v = '' end args[k] = v end return p._main(args) end return p bzc22v133v9z5yc4aisazripn6l94p8 ഫലകം:Protection padlock 10 7377 28460 2026-05-05T14:17:47Z w>Paine Ellsworth 0 sync to sandbox 28460 wikitext text/x-wiki <includeonly>{{#invoke:Protection banner|main}}</includeonly><noinclude> {{Documentation}} </noinclude> 0q651nfr0ibf5g4bbb3sw2qkj47h3ic 28461 28460 2026-07-12T16:12:54Z en>Codename Noreste 0 1 revision imported from [[:w:Template:Protection_padlock]]: Importing the main protection padlock template. 28460 wikitext text/x-wiki <includeonly>{{#invoke:Protection banner|main}}</includeonly><noinclude> {{Documentation}} </noinclude> 0q651nfr0ibf5g4bbb3sw2qkj47h3ic 28462 28461 2026-10-24T01:16:14Z Kiran Gopi 624 [[:en:Template:Protection_padlock]] എന്നതിൽ നിന്ന് 2 പതിപ്പുകൾ ഇറക്കുമതി ചെയ്തു 28460 wikitext text/x-wiki <includeonly>{{#invoke:Protection banner|main}}</includeonly><noinclude> {{Documentation}} </noinclude> 0q651nfr0ibf5g4bbb3sw2qkj47h3ic